diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-03-12 13:50:52 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-03-12 13:50:52 +0000 |
commit | edb4755a7ffe204195e054ca1c745e3cb93ea44b (patch) | |
tree | 96974c4dce34bc39d393bceb75b1e62307329c58 | |
parent | 3df36aed52ff4cbe26c19b8d0c0f26c3414237be (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr84485.c | 34 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 12 |
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, |