https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114040
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ah, I actually see the what's wrong. The destination store for the first limb in the loop look correct: if (_14 <= 3) goto <bb 6>; [80.00%] else goto <bb 7>; [20.00%] <bb 6> [local count: 1073741824]: bitint.3[_14] = _21; <bb 7> [local count: 1073741824]: i.e. if _14 is 0 or 2, we store something, otherwise we don't, because result __real__ only has 4 limbs. But the second limb store is wrong: if (_27 <= 3) goto <bb 12>; [80.00%] else goto <bb 15>; [20.00%] <bb 12> [local count: 1073741824]: if (_27 < 3) goto <bb 14>; [80.00%] else goto <bb 13>; [20.00%] <bb 13> [local count: 1073741824]: bitint.3[_27] = _30; goto <bb 15>; [100.00%] <bb 14> [local count: 858993464]: MEM[(unsigned long *)&bitint.3 + 24B] = _30; <bb 15> [local count: 1073741824]: It should be the other way around, if _27 < 3 (aka if it is 1), store bitint.3[_27] = _30; , if it is 3, MEM[(unsigned long *)&bitint.3 + 24B] = _30; and if it is > 3, don't store anything. I'm also surprised it doesn't mask off the most significant bit.