Tighten early exit in vect_analyze_data_ref_dependence (PR85586)

Message ID 87efivtebg.fsf@linaro.org
State New
Headers show
Series
  • Tighten early exit in vect_analyze_data_ref_dependence (PR85586)
Related show

Commit Message

Richard Sandiford May 1, 2018, 6:34 p.m.
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?

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.

Comments

Richard Biener May 2, 2018, 7:30 a.m. | #1
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 } } } */

Patch

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 } } } */