https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127877
Bug ID: 127877
Summary: [13/14/15/16/17 Regression] Wrong code with -O2
-march=x86-64-v3: nonlinear shift induction gives 0
instead of -1 since r13-2503-gc13223b790bbc5e4
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: kyuwoncho18 at gmail dot com
Target Milestone: ---
godbolt: https://godbolt.org/z/M4x1v69aG
```c
#include <stdio.h>
unsigned char b[256];
long long res_x;
unsigned res_s;
__attribute__((noinline)) void f (unsigned char *bb, long long init)
{
long long x = init;
unsigned s = 0;
for (int i = 0; i < 256; i++)
{
s += bb[i];
x >>= 3;
}
res_x = x;
res_s = s;
}
int main (int argc, char **argv)
{
int k = argc;
for (int i = 0; i < 256; i++)
b[i] = (unsigned char) (i + k);
f (b, -(long long) k);
printf ("%lld %u\n", res_x, res_s);
return 0;
}
```
```console
$ gcc -O2 -march=x86-64-v3 t.c && ./a.out
0 32640
$ gcc -O2 -march=x86-64-v3 -fno-tree-vectorize t.c && ./a.out
-1 32640
```
Expected `-1 32640`: `x` starts at `-1` and `-1 >> 3` stays `-1`.
In `vectorizable_nonlinear_induction`, the `vect_step_op_shr` check rejects the
induction only if `nunits * step >= TYPE_PRECISION`, but the latch update is
built from `vf` (`vect_create_nonlinear_iv_step (..., vf, ...)`). Here the
`unsigned char` loads give a larger VF than the `long long` vector's `nunits`,
so the vector shift count is `vf * 3` = 96 for a 64-bit element. The `shl` case
has the same check.
GCC 12.2 works; 13.1 through trunk (17.0.0 20261012) fail. Both the check and
the `vf` call site are unchanged since r13-2503-gc13223b790b, which added
nonlinear induction vectorization.
Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.