On Sat, Jun 27, 2026 at 11:22:06AM +0200, Jakub Jelinek wrote: > Hi! > > The following testcase is miscompiled since r16-3301 but the problem is much > older. > The *brx_stage1_<GPR:mode> define_insn_and_split pattern doesn't describe > that it clobbers CC_REGNUM, but splits (before reload) into something which > does clobber CC_REGNUM unconditionally. > Since r16-3301 on this testcase the late_combine1 pass figures it can extend > the lifetime of CC_REGNUM across such an instruction, but when it is in > split1 pass split into something that does clobber CC_REGNUM, the value from > earlier comparison till later use is not preserved anymore. > > The following patch fixes it by adding clobber for CC_REGNUM even to the > *brx_stage1_<GPR:mode> pattern, so that df/late_combine etc. know that it is > CC_REGNUM is clobbered by it. > I had to put the clobber before the match_scratch clobber, otherwise there > is endless loop trying to split this insn in split1 pass, the insn it is > split into matches the pattern again and is split again etc. forever. > Even with this patch combine can match this insn, we have code to add the > missing clobbers if the register isn't live across it. > > Bootstrapped/regtested on s390x-linux, also tested on the veusz package > which now passes its testsuite (and didn't before). Ok for trunk/16 > and perhaps even older release branches (where it is just latent)?
Ok for trunk and I agree that we should apply this to all older release branches which are still open. Thanks for fixing this! Cheers, Stefan > > 2026-06-27 Jakub Jelinek <[email protected]> > > PR target/125992 > * config/s390/s390.md (*brx_stage1_<GPR:mode>): Add CC_REGNUM clobber. > > * gcc.target/s390/pr125992.c: New test. > > --- gcc/config/s390/s390.md.jj 2026-06-02 08:15:04.576141861 +0200 > +++ gcc/config/s390/s390.md 2026-06-26 01:23:35.038623318 +0200 > @@ -10256,6 +10256,7 @@ (define_insn_and_split "*brx_stage1_<GPR > (pc))) > (set (match_operand:GPR 4 "nonimmediate_operand" "") > (plus:GPR (match_dup 1) (match_dup 2))) > + (clobber (reg:CC CC_REGNUM)) > (clobber (match_scratch:GPR 5 ""))] > "" > "#" > --- gcc/testsuite/gcc.target/s390/pr125992.c.jj 2026-06-26 > 08:58:11.720734276 +0200 > +++ gcc/testsuite/gcc.target/s390/pr125992.c 2026-06-26 08:57:45.265070843 > +0200 > @@ -0,0 +1,41 @@ > +/* PR target/125992 */ > +/* { dg-do run { target s390_useable_hw } } */ > +/* { dg-options "-O2 -march=z13" } */ > + > +long a, b, c, d[4]; > + > +[[gnu::noipa]] long > +foo () > +{ > + return d[c++]; > +} > + > +[[gnu::noipa]] void > +bar () > +{ > + long e = 0; > + for (;;) > + { > + e += a; > + a = foo (); > + if (b + a > e) > + return; > + if (a == 0) > + break; > + if (a > 0) > + b += a; > + } > +} > + > +int > +main () > +{ > + a = 16; > + b = -64; > + c = 0; > + d[0] = 64; > + d[1] = 128; > + bar (); > + if (b != 0) > + __builtin_abort (); > +} > > Jakub >
