https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120547
Bug ID: 120547 Summary: Wrong-code due to real_from_integer Product: gcc Version: 16.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- #define CHECK(x, y) \ if ((double) x != (double) y || (double) (x + 1) != (double) (y + 1)) \ __builtin_abort () int main () { unsigned long long a = 0x20000000000001ULL << 7; volatile unsigned long long b = a; CHECK (a, b); unsigned _BitInt(4096) c = ((unsigned _BitInt(4096)) 0x20000000000001ULL) << 253; volatile unsigned _BitInt(4096) d = c; CHECK (c, d); unsigned _BitInt(4096) e = ((unsigned _BitInt(4096)) 0x20000000000001ULL) << 931; volatile unsigned _BitInt(4096) f = e; CHECK (e, f); } is miscompiled in GCC 14+ (when _BitInt support has been added). int maxbitlen = MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT; and /* We have to ensure we can negate the largest negative number. */ wide_int val = wide_int::from (val_in, maxbitlen, sgn); have not been adjusted for _BitInt. And another bug is in /* This value is too large, we must shift it right to preserve all the bits we can, and then bump the exponent up by that amount. */ val = wi::lrshift (val, e); This throws away the low bits, while I think we should or in 1 if any of the shifted away bits are non-zero (so the kind of sticky shift which e.g. soft-fp is doing).