summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2018-03-12 13:50:52 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2018-03-12 13:50:52 +0000
commitedb4755a7ffe204195e054ca1c745e3cb93ea44b (patch)
tree96974c4dce34bc39d393bceb75b1e62307329c58
parent3df36aed52ff4cbe26c19b8d0c0f26c3414237be (diff)
downloadgcc-edb4755a7ffe204195e054ca1c745e3cb93ea44b.tar.gz
Don't vectorise zero-step rmw operations (PR 84485)
GCC 6 and 7 would vectorise: void f (unsigned long incx, unsigned long incy, float *restrict dx, float *restrict dy) { unsigned long ix = 0, iy = 0; for (unsigned long i = 0; i < 512; ++i) { dy[iy] += dx[ix]; ix += incx; iy += incy; } } without first proving that incy is nonzero. This is a regression from GCC 5. It was fixed on trunk in r256644, which versioned the loop based on whether incy is zero, but that's obviously too invasive to backport. This patch instead bails out for possibly-zero steps in the place that trunk would try a check for zeroness. Also, the patch makes vect_analyze_data_ref_access check safelen as well as force_vectorize. 2018-03-12 Richard Sandiford <richard.sandiford@linaro.org> gcc/ PR tree-optimization/84485 * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Return true for zero dependence distances if the step might be zero, and if there is no metadata that guarantees correctness. (vect_analyze_data_ref_access): Check safelen as well as force_vectorize. gcc/testsuite/ PR tree-optimization/84485 * gcc.dg/vect/pr84485.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@258450 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr84485.c34
-rw-r--r--gcc/tree-vect-data-refs.c12
4 files changed, 59 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e8c5918d61..4c39ba0bb3d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2018-03-12 Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR tree-optimization/84485
+ * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Return
+ true for zero dependence distances if the step might be zero,
+ and if there is no metadata that guarantees correctness.
+ (vect_analyze_data_ref_access): Check safelen as well as
+ force_vectorize.
+
2018-03-11 John David Anglin <danglin@gcc.gnu.org>
Backport from mainline
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 633b17a7a84..e6bcebabf26 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-12 Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR tree-optimization/84485
+ * gcc.dg/vect/pr84485.c: New test.
+
2018-03-10 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/84734
diff --git a/gcc/testsuite/gcc.dg/vect/pr84485.c b/gcc/testsuite/gcc.dg/vect/pr84485.c
new file mode 100644
index 00000000000..ad25d3642c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr84485.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+#define N 256
+
+void __attribute__ ((noinline, noclone))
+f (unsigned long incx, unsigned long incy,
+ float *restrict dx, float *restrict dy)
+{
+ unsigned long ix = 0, iy = 0;
+ for (unsigned long i = 0; i < N; ++i)
+ {
+ dy[iy] += dx[ix];
+ ix += incx;
+ iy += incy;
+ }
+}
+
+float a = 0.0;
+float b[N];
+
+int
+main (void)
+{
+ check_vect ();
+
+ for (int i = 0; i < N; ++i)
+ b[i] = i;
+ f (1, 0, b, &a);
+ if (a != N * (N - 1) / 2)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index ccaa945bffb..f0e97060d7b 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -394,6 +394,16 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
}
}
+ unsigned int step_prec = TYPE_PRECISION (TREE_TYPE (DR_STEP (dra)));
+ if (loop->safelen < 2
+ && !expr_not_equal_to (DR_STEP (dra), wi::zero (step_prec)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "step could be zero.\n");
+ return true;
+ }
+
continue;
}
@@ -2515,7 +2525,7 @@ vect_analyze_data_ref_access (struct data_reference *dr)
/* Allow references with zero step for outer loops marked
with pragma omp simd only - it guarantees absence of
loop-carried dependencies between inner loop iterations. */
- if (!loop->force_vectorize)
+ if (!loop->force_vectorize || loop->safelen < 2)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,