vect_truncate_gather_scatter_offset bounds the offsets { 0, X, X*2, ... }
by the latch iteration count, but peeling for alignment by masking
shifts the active lanes up by the number of skipped iterations.  With
-msve-vector-bits=256 the new tests access lane 7 through the 32-bit
offset 7 * 650000000, which wraps.  Do not lower the bound when peeling
for alignment, since whether a mask will do the peeling is not yet known.
GCC 11 onwards have the same wrong code.

Bootstrapped and regression tested on x86_64-pc-linux-gnu; regression
tested on aarch64-linux-gnu (qemu, default and SVE-256 boards).

Assisted-by: Claude Opus 5 (Anthropic)

gcc/ChangeLog:

        * tree-vect-stmts.cc (vect_truncate_gather_scatter_offset): Do not
        lower the element count to the latch iteration count when peeling
        for alignment.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/sve/strided_load_9.c: New test.
        * gcc.target/aarch64/sve/strided_store_8.c: New test.

Signed-off-by: Dominic P <[email protected]>
---
 .../gcc.target/aarch64/sve/strided_load_9.c      | 16 ++++++++++++++++
 .../gcc.target/aarch64/sve/strided_store_8.c     | 16 ++++++++++++++++
 gcc/tree-vect-stmts.cc                           |  6 ++++--
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/strided_load_9.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/strided_store_8.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/strided_load_9.c 
b/gcc/testsuite/gcc.target/aarch64/sve/strided_load_9.c
new file mode 100644
index 00000000000..b5e793f4394
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/strided_load_9.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O3 -fno-vect-cost-model -msve-vector-bits=256 
-mautovec-preference=sve-only" } */
+
+int x[8] __attribute__ ((aligned (64)));
+
+void
+foo (int *restrict b, unsigned int n)
+{
+  for (unsigned int i = 1; i < n; ++i)
+    x[i] = b[i * 650000000L];
+}
+
+/* Peeling for alignment by masking makes lane 7 active; 7 * 650000000
+   does not fit in 32 bits.  */
+/* { dg-final { scan-assembler-not {\tld1w\tz[0-9]+\.s, p[0-7]/z, \[x[0-9]+, 
z[0-9]+\.s, [su]xtw} } } */
+/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d, p[0-7]/z, \[x[0-9]+, 
z[0-9]+\.d\]} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/strided_store_8.c 
b/gcc/testsuite/gcc.target/aarch64/sve/strided_store_8.c
new file mode 100644
index 00000000000..6e6602eb923
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/strided_store_8.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O3 -fno-vect-cost-model -msve-vector-bits=256 
-mautovec-preference=sve-only" } */
+
+int x[8] __attribute__ ((aligned (64)));
+
+void
+bar (int *restrict b, unsigned int n)
+{
+  for (unsigned int i = 1; i < n; ++i)
+    b[i * 650000000L] = x[i];
+}
+
+/* Peeling for alignment by masking makes lane 7 active; 7 * 650000000
+   does not fit in 32 bits.  */
+/* { dg-final { scan-assembler-not {\tst1w\tz[0-9]+\.s, p[0-7], \[x[0-9]+, 
z[0-9]+\.s, [su]xtw} } } */
+/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.d, p[0-7], \[x[0-9]+, 
z[0-9]+\.d\]} 2 } } */
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 244f319d0e4..1db6786078e 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -1653,10 +1653,12 @@ vect_truncate_gather_scatter_offset (stmt_vec_info 
stmt_info, tree vectype,
      Start with the maximum vectorization factor.  */
   unsigned HOST_WIDE_INT count = vect_max_vf (loop_vinfo) - 1;
 
-  /* Try lowering COUNT to the number of scalar latch iterations.  */
+  /* Try lowering COUNT to the number of scalar latch iterations.
+     Peeling for alignment by masking shifts the active lanes up.  */
   class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   widest_int max_iters;
-  if (max_loop_iterations (loop, &max_iters)
+  if (!LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
+      && max_loop_iterations (loop, &max_iters)
       && max_iters < count)
     count = max_iters.to_shwi ();
 
-- 
2.55.0

Reply via email to