When we validate the shift amount for a non-linear shift induction
we only consider nunits shift count updates rather than VF ones.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/127877
        * tree-vect-loop.cc (vectorizable_nonlinear_induction): Fix
        shift count check.

        * gcc.dg/vect/vect-pr127877.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/vect-pr127877.c | 37 +++++++++++++++++++++++
 gcc/tree-vect-loop.cc                     |  9 +++---
 2 files changed, 41 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr127877.c

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 00000000000..f71ebb55140
--- /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 71623e7afaa..02c3bf1d935 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -9338,9 +9338,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;
@@ -9350,12 +9350,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:

base-commit: 5d74e9640ebebb10abab61cfd20631dbe6a97dcc
prerequisite-patch-id: e52d299db98b0892f974152cd9fa5f6859fec5b7
prerequisite-patch-id: 39da6ec3264bae454fa504f127cd5b80a0662f04
prerequisite-patch-id: 6d6c263a964425334ad8c2edd4dd89dcbff44bfe
prerequisite-patch-id: 9a12a1706cbdff1edf8959682cd3cf9d900cd8f1
prerequisite-patch-id: dcb6febf1dbf6ea505f87a9c8c3572804a12819e
prerequisite-patch-id: b24057443c46d6979436cce479836178b19355de
prerequisite-patch-id: d61bf2c4249ecd3d9da5eeda002d332ed3a8b4fd
prerequisite-patch-id: 59cbeca60f782f48f945bc532c2235a50de6f0e5
prerequisite-patch-id: 8eddd3172e2007d0fc591124a56b372dfe83e683
prerequisite-patch-id: 862842dd3742066d039f66ffe9528bc490308c50
prerequisite-patch-id: e413d39d9af45f25483eaf229cf883c771444fbb
prerequisite-patch-id: 2faef186ad1d816bb104d89638bc4cec6d863a46
prerequisite-patch-id: b32cceb111f4f57798e4b1d58822281e7bbaf25e
prerequisite-patch-id: 404fd84b023dbe3994be05f26d6a86e83486d405
-- 
2.51.0

Reply via email to