Since this patch is sitting in the queue for quite some time and (more importantly?) solves a bootstrap problem let me reiterate:
While writing the initial commit 7cdd0860949c6c3232e6cff1d7ca37bb5234074c and the subsequent (potential) fix 41ef5a34161356817807be3a2e51fbdbe575ae85 I was not aware of the fact that the normal form of a CONST_INT, representing an unsigned integer with fewer bits than in HOST_WIDE_INT, is a sign-extended version of the unsigned integer. This invariant is checked in rtl.h where we have at line 2297: case CONST_INT: if (precision < HOST_BITS_PER_WIDE_INT) /* Nonzero BImodes are stored as STORE_FLAG_VALUE, which on many targets is 1 rather than -1. */ gcc_checking_assert (INTVAL (x.first) == sext_hwi (INTVAL (x.first), precision) || (x.second == BImode && INTVAL (x.first) == 1)); This was pretty surprising and frankly speaking unintuitive to me which is why I was skimming further over existing code where I have found this in combine.cc: /* (unsigned) < 0x80000000 is equivalent to >= 0. */ else if (is_a <scalar_int_mode> (mode, &int_mode) && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT && ((unsigned HOST_WIDE_INT) const_op == HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1))) { The expression of the if-statement is a contradiction rendering the then-part unreachable unless you mask out the upper bits of the sign-extended unsigned integer const_op (as proposed in the inlined patch): ((unsigned HOST_WIDE_INT) const_op & GET_MODE_MASK (int_mode)) This is why I got a bit uncertain and hoped to get some feedback whether my intuition is correct or not. Meanwhile I also found a comment in the internals book at "14.7 Constant Expression Types" where we have: "Constants generated for modes with fewer bits than in HOST_WIDE_INT must be sign extended to full width (e.g., with gen_int_mode). [...] Note however that values are neither inherently signed nor inherently unsigned; where necessary, signedness is determined by the rtl operation instead." At least this and the assert statement document that the normal form of a CONST_INT is kind of special w.r.t. unsigned integers. Is there anyone who can shed some light on _why_ such a normal form was chosen? Independent of why such a normal form was chosen, this patch restores the normal form and solves the bootstrap problem for Loongarch. Cheers, Stefan