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