https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126594
Bug ID: 126594
Summary: [16/17 Regression] Wrong code with early-break
vectorisation and vect_peel_nonlinear_iv_init
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
/* tree-vect-loop.cc:9066 -- vect_peel_nonlinear_iv_init switches off the
out-of-range shift-count guard on the early-break path (the `&&
!early_exit_p`
conjunct), so the scalar epilogue's start value for a `x >>= c` / `x <<= c`
induction is computed as a bare `init >> (K*step)` with a *runtime* K. Once
K*step >= the type precision that expression is undefined in GIMPLE and on
aarch64 it degenerates to a shift by (K*step % prec), so the epilogue starts
from a wrong value instead of 0.
The array must be file scope and over-aligned. With unknown alignment the
early break forces peeling for alignment and vect_can_peel_nonlinear_iv_p
rejects the nonlinear IV, which masks the bug. */
int a[256] __attribute__((aligned (64)));
__attribute__((noipa)) unsigned
f_shr (void)
{
unsigned x = 0x80000000u;
for (int i = 0; i < 100; i++) /* constant trip count is required */
{
if (a[i] == 42)
break; /* early exit */
x >>= 1; /* vect_step_op_shr, step 1 */
}
return x; /* live out => EARLY_BRK_NEEDS_EPILOG */
}
__attribute__((noipa)) unsigned
f_shl (void)
{
unsigned x = 1;
for (int i = 0; i < 100; i++)
{
if (a[i] == 42)
break;
x <<= 1; /* vect_step_op_shl, step 1 */
}
return x;
}
int
main (void)
{
for (int k = 0; k < 100; k++)
{
for (int i = 0; i < 256; i++)
a[i] = 1;
a[k] = 42;
/* k shifts of a 32-bit unsigned: the value is 0 once k >= 32. */
unsigned want_shr = k >= 32 ? 0u : (0x80000000u >> k);
unsigned got_shr = f_shr ();
if (got_shr != want_shr)
__builtin_abort ();
unsigned want_shl = k >= 32 ? 0u : (1u << k);
unsigned got_shl = f_shl ();
if (got_shl != want_shl)
__builtin_abort ();
}
return 0;
}
aborts on aarch64 at -O3 and passes without vectorisation