https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64172
--- Comment #13 from Vladimir Makarov <vmakarov at gcc dot gnu.org> --- I've investigated the generated code. The problem is in IRA live-range splitting on the region borders. The pseudo to consider is 157 which contains local_prng.d in the following code void randmemset (prng_t *prng, uint8_t *buf, size_t size) { prng_t local_prng = *prng; .... while (size > 0) { uint32_t e = local_prng.p0.a - ((local_prng.p0.b << 27) + (local_prng.p0.b >> (32 - 27))); local_prng.p0.a = local_prng.p0.b ^ ((local_prng.p0.c << 17) ^ (local_prng.p0.c >> (32 - 17))); local_prng.p0.b = local_prng.p0.c + local_prng.p0.d; local_prng.p0.c = local_prng.p0.d + e; local_prng.p0.d = e + local_prng.p0.a; *buf++ = local_prng.p0.d; size--; } => *prng = local_prng; } The pseudo gets different hard regs in different regions Disposition: ... 8:r155 l0 mem 40:r157 l1 8 25:r157 l2 6 6:r157 l0 4 ... In the loop above, it gets 6, outside the loop it gets 4. On the exit from the loop, IRA generates 157:TI = 308:TI 308 is created from 157 to be used in the loop. The insn is split on 4 insns: 449: r157:TI#0=r308:TI#0 450: r157:TI#4=r308:TI#4 451: r157:TI#8=r308:TI#8 452: r157:TI#12=r308:TI#12 In order words, in terms of hard regs we do 6<-4; 7<-5; 8<-6; 9<-7. The two last insns use wrong values. I'll think how to fix it better. I hope that the fix will be ready at the end of next week.