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