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
> 

Reply via email to