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.

Reply via email to