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

            Bug ID: 125992
           Summary: [16/17 Regression] veusz miscompilation on s390x with
                    -march=z13 -O2 since r16-3301
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

The following testcase is miscompiled on s390x-linux since
r16-3301-g724d88900b7aa8f249b737a33e9b11eedf48ebae
at -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 ();
}

The problem is in the *brx_stage1_<GPR:mode> define_insn_and_split, which
splits a conditional jump combined with addition into the same thing with tied
up inputs into a two register pair (at least in my limited understanding), the
pattern
of that define_insn_and_split doesn't clobber CC_REGNUM, but what it splits
into does.  And it is split unconditionally, without checking if CC isn't live
across that instruction.
And r16-3301 is a change that makes CC live across that instruction.

Reply via email to