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

liu zhenyu <lzy20000419 at outlook dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lzy20000419 at outlook dot com

--- Comment #5 from liu zhenyu <lzy20000419 at outlook dot com> ---
r17-5542 fixes the match.pd merge, but the same problem (the index range [0,
2N) handled in the 8-bit mask element type) is also in vector lowering, and
that one still fails on trunk. It needs only -O0:

```c
typedef signed char V __attribute__((vector_size (256)));
V x, r, m;
__attribute__((noipa)) void f (void) { r = __builtin_shuffle (x, m); }
int main ()
{
  for (int i = 0; i < 256; i++) { x[i] = i & 0x7f; m[i] = i; }
  m[0] = -1; m[1] = -128;
  f ();
  if (r[0] != x[255] || r[1] != x[128] || r[2] != x[2])
    __builtin_abort ();
  return 0;
}
```

```
$ gcc -O0 t.c && ./a.out
Aborted
```

Expected: no abort. The mask is taken modulo N (256 here), so -1 selects x[255]
and -128 selects x[128]. Fails with 14.2.0 and 17.0.0 (20261105, includes
r17-5542).

In lower_vec_perm (tree-vect-generic.cc:1652), variable-mask path, the index is
reduced with `build_int_cst (mask_elt_type, elements - 1)` (:1741) and the
two-operand select uses `build_int_cst (mask_elt_type, elements)` (:1735). With
256 elements and a signed char mask element these are -1 and 0, so the AND does
not reduce the index and the negative index reads outside the spilled vector.
Doing the masking in an unsigned type of at least sizetype precision, as
r17-5542 does with ssizetype, should fix it. This part is not a regression, so
it may be better tracked separately; I can open a new PR if preferred.

Disclaimer: This test case was found with LLM-assisted targeted testing, and
the report was written with LLM assistance.

Reply via email to