gcc/ChangeLog:

        * tree-vect-loop.cc: Add ranger check to check if VF is safe.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/sve/vect-safe-max-vf.c: New test.
        * gcc.target/aarch64/sve/vect-safe-max-vf2.c: New test.

-- >8 --

This is a little hacky as it ends up taking a poly int, making a const
tree GENERIC representation of it, then using ranger logic on that
which converts it back to a poly int.

Regr tested and bootstrapped on aarch64-linux-gnu, armhf-linux-gnu,
x86_64-linux-gnu.
(Requires my aarch64: Add --param=aarch64-autovec-mode patch for the
tests)

Okay for master?

KR,
Alfie
---
 .../gcc.target/aarch64/sve/vect-safe-max-vf.c     | 15 +++++++++++++++
 .../gcc.target/aarch64/sve/vect-safe-max-vf2.c    | 15 +++++++++++++++
 gcc/tree-vect-loop.cc                             | 11 ++++++++++-
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf2.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf.c 
b/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf.c
new file mode 100644
index 00000000000..cfd88ab1318
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all 
-fno-vect-cost-model --param=aarch64-autovec-mode=VNx16QI" } */
+
+void foo1 (char *a, unsigned n) {
+    for (int i = 0; i < n; ++i)
+      a[i+256] += a[i];
+}
+
+void foo2 (char *a, unsigned n) {
+    for (int i = 0; i < n; ++i)
+      a[i+255] += a[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump "bad data dependence" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf2.c 
b/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf2.c
new file mode 100644
index 00000000000..631a21e21ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-safe-max-vf2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all 
-fno-vect-cost-model --param=aarch64-autovec-mode=VNx4QI" } */
+
+void foo3 (int *a, unsigned n) {
+    for (int i = 0; i < n; ++i)
+      a[i+64] += a[i];
+}
+
+void foo4 (int *a, unsigned n) {
+    for (int i = 0; i < n; ++i)
+      a[i+63] += a[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump "bad data dependence" "vect" } } */
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 9b2afad6034..656039d2b32 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -2338,7 +2338,16 @@ start_over:
 
   if (max_vf != MAX_VECTORIZATION_FACTOR
       && maybe_lt (max_vf, LOOP_VINFO_VECT_FACTOR (loop_vinfo)))
-    return opt_result::failure_at (vect_location, "bad data dependence.\n");
+    {
+      tree vf = build_int_cst (sizetype, vectorization_factor);
+      /* If the max_vf is less than the upper bound of the vectorization
+         factor, then this is not safe.  */
+      int_range_max r;
+      get_range_query (cfun)->range_of_expr (r, vf);
+      if (r.varying_p () || r.undefined_p ()
+         || wi::ltu_p (max_vf, r.upper_bound ()))
+       return opt_result::failure_at (vect_location, "bad data dependence.\n");
+    }
 
   loop_vinfo->vector_costs = init_cost (loop_vinfo, false);
 
-- 
2.55.0

Reply via email to