https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70123

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The __builtin_strcat in the testcase should be __builtin_strcpy, it reproduces
even with that and without it it has UB.

Anyway, what I see is that the f9 call loads the g variable into %r6 register
(for argument passing, but on s390* the register is call-saved), we have:
%r6 = (reg:DI 180 [g])
before the f9 call and
(reg:DI 250 [g]) = (reg:DI 180 [g])
after the f9 call.  Pseudo 250 is then used in the problematic loop as doloop
counter.  sched1 then moves these two insns before the bar call shortly before
f9, next to each other.
Then IRA performs:
New iteration of spill/restore move
      Changing RTL for loop 2 (header bb20)
  10 vs parent 10:      Creating newreg=256 from oldreg=180
  13 vs parent 11:      Creating newreg=257 from oldreg=240
  9 vs parent 13:      Creating newreg=258 from oldreg=246
  8 vs parent 8:      Creating newreg=259 from oldreg=247
  7 vs parent 7:      Creating newreg=260 from oldreg=248
What we get out of LRA looks already wrong.
There is an added spill of %r6 (which contains something unrelated to g), then
after a few instructions correct %r6 = %r10 (%r10 holds the correct value of g
at that point at least in the first iteration that I could verify) before the
bar call, then the bar call itself (which shouldn't change %r6, because it is
call-saved register), then the call to f9, and right after it LRA adds a fill
from the above mentioned spill slot (so unrelated value) into %r6 and copy of
that %r6 into %r10.

Reply via email to