https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119707
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- __attribute__((noipa)) unsigned _BitInt(256) foo (_BitInt(129) x) { return (unsigned _BitInt(255)) x; } int main () { if (foo (-1) != 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffuwb) __builtin_abort (); } works though, there it copies the two lowest limbs, for the third one sign extends the single bit and for the last one masks the previous value to 63 unsigned bits. I think the bug is in <bb 3> [local count: 1073741824]: # _8 = PHI <0(2), _9(12)> # _10 = PHI <0(2), _11(12)> # _22 = PHI <0(2), _23(12)> ... # _20 = PHI <0(5), _10(3), _18(6)> _11 = _20; ... <bb 11> [local count: 214748360]: _30 = (<unnamed-unsigned:63>) _10; _31 = (unsigned long) _30; where _10 is the PHI tracking the bits from sign extension, _18 is what is set in the idx == 2 handling in the first half of the loop and bb 11 is the handling of idx == 3 for the outer cast (u255 -> u256), where in this case it should be using _11 rather than _10. I think this was caused by PR112941 r14-6742 change, but now to figure out when to use m_data[save_data_cnt] and when to use m_data[save_date_cnt + 1]...