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.