https://gcc.gnu.org/g:b24bee5c07afb8c90c02597527871a44b00c4fd5

commit r17-5178-gb24bee5c07afb8c90c02597527871a44b00c4fd5
Author: Richard Biener <[email protected]>
Date:   Tue Oct 13 19:51:01 2026 +0200

    tree-optimization/127877 - wrong code with non-linear induction 
vectorization
    
    When we validate the shift amount for a non-linear shift induction
    we only consider nunits shift count updates rather than VF ones.
    
            PR tree-optimization/127877
            * tree-vect-loop.cc (vectorizable_nonlinear_induction): Fix
            shift count check.
    
            * gcc.dg/vect/vect-pr127877.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/vect-pr127877.c | 37 +++++++++++++++++++++++++++++++
 gcc/tree-vect-loop.cc                     |  9 ++++----
 2 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr127877.c 
b/gcc/testsuite/gcc.dg/vect/vect-pr127877.c
new file mode 100644
index 000000000000..f71ebb55140a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr127877.c
@@ -0,0 +1,37 @@
+/* { dg-additional-options "-mavx2" { target avx2 } } */
+
+#include "tree-vect.h"
+
+typedef __INT64_TYPE__ int64_t;
+unsigned char b[256];
+int64_t res_x;
+unsigned res_s;
+
+__attribute__((noipa)) void
+f (unsigned char *bb, int64_t init)
+{
+  int64_t 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 ()
+{
+  check_vect ();
+
+#pragma GCC novector
+  for (int i = 0; i < 256; i++)
+    b[i] = (unsigned char) (i + 1);
+
+  f (b, -1);
+  if (res_x != -1 || res_s != 32640)
+    __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index b6f906ac465c..b2639444ebdb 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -9333,9 +9333,9 @@ vectorizable_nonlinear_induction (loop_vec_info 
loop_vinfo,
       if (!directly_supported_p (RSHIFT_EXPR, vectype, optab_vector))
        return false;
 
-      /* Don't shift more than type precision to avoid UD.  */
+      /* Don't shift more than type precision to avoid UB.  */
       if (!tree_fits_uhwi_p (step_expr)
-         || maybe_ge (nunits * tree_to_uhwi (step_expr),
+         || maybe_ge (vf * tree_to_uhwi (step_expr),
                       TYPE_PRECISION (TREE_TYPE (init_expr))))
        return false;
       break;
@@ -9345,12 +9345,11 @@ vectorizable_nonlinear_induction (loop_vec_info 
loop_vinfo,
       if (!directly_supported_p (LSHIFT_EXPR, vectype, optab_vector))
        return false;
 
-      /* Don't shift more than type precision to avoid UD.  */
+      /* Don't shift more than type precision to avoid UB.  */
       if (!tree_fits_uhwi_p (step_expr)
-         || maybe_ge (nunits * tree_to_uhwi (step_expr),
+         || maybe_ge (vf * tree_to_uhwi (step_expr),
                       TYPE_PRECISION (TREE_TYPE (init_expr))))
        return false;
-
       break;
 
     default:

Reply via email to