Message ID | 87efivtebg.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Tighten early exit in vect_analyze_data_ref_dependence (PR85586) | expand |
On Tue, May 1, 2018 at 8:34 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > The problem in this PR was that we didn't consider aliases between > writes in the same strided group. After tightening the early exit > we get the expected abs(step) >= 2 versioning check. > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK for trunk > and GCC 8? OK for trunk and branch. Thanks, Richard. > Thanks, > Richard > > > 2018-05-01 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > PR tree-optimization/85586 > * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Only > exit early for statements in the same group if the accesses are > not strided. > > gcc/testsuite/ > PR tree-optimization/85586 > * gcc.dg/vect/pr85586.c: New test. > > Index: gcc/tree-vect-data-refs.c > =================================================================== > --- gcc/tree-vect-data-refs.c 2018-05-01 19:30:22.344979421 +0100 > +++ gcc/tree-vect-data-refs.c 2018-05-01 19:32:10.404466158 +0100 > @@ -305,9 +305,11 @@ vect_analyze_data_ref_dependence (struct > return false; > > /* We do not have to consider dependences between accesses that belong > - to the same group. */ > + to the same group, unless the stride could be smaller than the > + group size. */ > if (GROUP_FIRST_ELEMENT (stmtinfo_a) > - && GROUP_FIRST_ELEMENT (stmtinfo_a) == GROUP_FIRST_ELEMENT (stmtinfo_b)) > + && GROUP_FIRST_ELEMENT (stmtinfo_a) == GROUP_FIRST_ELEMENT (stmtinfo_b) > + && !STMT_VINFO_STRIDED_P (stmtinfo_a)) > return false; > > /* Even if we have an anti-dependence then, as the vectorized loop covers at > Index: gcc/testsuite/gcc.dg/vect/pr85586.c > =================================================================== > --- /dev/null 2018-04-20 16:19:46.369131350 +0100 > +++ gcc/testsuite/gcc.dg/vect/pr85586.c 2018-05-01 19:32:10.403466206 +0100 > @@ -0,0 +1,43 @@ > +#define N 100 > + > +void __attribute__ ((noipa)) > +foo (int *out, int *in, int step) > +{ > + for (int i = 0; i < N; ++i) > + { > + out[0] = in[i]; > + out[1] = 2; > + out += step; > + } > +} > + > +int in[N]; > +int out[N * 2]; > + > +int > +main (void) > +{ > + for (int i = 0; i < N; ++i) > + { > + in[i] = i * (i + 1); > + asm volatile ("" ::: "memory"); > + } > + > + foo (out, in, 1); > + for (int i = 0; i < N; ++i) > + if (out[i] != in[i]) > + __builtin_abort (); > + if (out[N] != 2) > + __builtin_abort (); > + > + foo (out + N - 1, in, -1); > + if (out[0] != in[N - 1]) > + __builtin_abort (); > + for (int i = 1; i <= N; ++i) > + if (out[i] != 2) > + __builtin_abort (); > + > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" { target vect_int } } } */
Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2018-05-01 19:30:22.344979421 +0100 +++ gcc/tree-vect-data-refs.c 2018-05-01 19:32:10.404466158 +0100 @@ -305,9 +305,11 @@ vect_analyze_data_ref_dependence (struct return false; /* We do not have to consider dependences between accesses that belong - to the same group. */ + to the same group, unless the stride could be smaller than the + group size. */ if (GROUP_FIRST_ELEMENT (stmtinfo_a) - && GROUP_FIRST_ELEMENT (stmtinfo_a) == GROUP_FIRST_ELEMENT (stmtinfo_b)) + && GROUP_FIRST_ELEMENT (stmtinfo_a) == GROUP_FIRST_ELEMENT (stmtinfo_b) + && !STMT_VINFO_STRIDED_P (stmtinfo_a)) return false; /* Even if we have an anti-dependence then, as the vectorized loop covers at Index: gcc/testsuite/gcc.dg/vect/pr85586.c =================================================================== --- /dev/null 2018-04-20 16:19:46.369131350 +0100 +++ gcc/testsuite/gcc.dg/vect/pr85586.c 2018-05-01 19:32:10.403466206 +0100 @@ -0,0 +1,43 @@ +#define N 100 + +void __attribute__ ((noipa)) +foo (int *out, int *in, int step) +{ + for (int i = 0; i < N; ++i) + { + out[0] = in[i]; + out[1] = 2; + out += step; + } +} + +int in[N]; +int out[N * 2]; + +int +main (void) +{ + for (int i = 0; i < N; ++i) + { + in[i] = i * (i + 1); + asm volatile ("" ::: "memory"); + } + + foo (out, in, 1); + for (int i = 0; i < N; ++i) + if (out[i] != in[i]) + __builtin_abort (); + if (out[N] != 2) + __builtin_abort (); + + foo (out + N - 1, in, -1); + if (out[0] != in[N - 1]) + __builtin_abort (); + for (int i = 1; i <= N; ++i) + if (out[i] != 2) + __builtin_abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" { target vect_int } } } */