Don't allow unsafe reductions in graphite
authorTom de Vries <tom@codesourcery.com>
Fri, 24 Jul 2015 20:55:22 +0000 (20:55 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Fri, 24 Jul 2015 20:55:22 +0000 (20:55 +0000)
2015-07-24  Tom de Vries  <tom@codesourcery.com>

* graphite-sese-to-poly.c (is_reduction_operation_p): Limit
flag_associative_math to FLOAT_TYPE_P.  Honour
TYPE_OVERFLOW_WRAPS for INTEGRAL_TYPE_P. Don't allow any other types.

* gcc.dg/graphite/block-1.c: Xfail scan.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/uns-block-1.c: New test.
* gcc.dg/graphite/uns-interchange-12.c: New test.
* gcc.dg/graphite/uns-interchange-14.c: New test.
* gcc.dg/graphite/uns-interchange-15.c: New test.
* gcc.dg/graphite/uns-interchange-9.c: New test.
* gcc.dg/graphite/uns-interchange-mvt.c: New test.

From-SVN: r226193

15 files changed:
gcc/ChangeLog
gcc/graphite-sese-to-poly.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/block-1.c
gcc/testsuite/gcc.dg/graphite/interchange-12.c
gcc/testsuite/gcc.dg/graphite/interchange-14.c
gcc/testsuite/gcc.dg/graphite/interchange-15.c
gcc/testsuite/gcc.dg/graphite/interchange-9.c
gcc/testsuite/gcc.dg/graphite/interchange-mvt.c
gcc/testsuite/gcc.dg/graphite/uns-block-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c [new file with mode: 0644]

index 2645708..3bd8ff1 100644 (file)
@@ -1,3 +1,9 @@
+2015-07-24  Tom de Vries  <tom@codesourcery.com>
+
+       * graphite-sese-to-poly.c (is_reduction_operation_p): Limit
+       flag_associative_math to FLOAT_TYPE_P.  Honour
+       TYPE_OVERFLOW_WRAPS for INTEGRAL_TYPE_P. Don't allow any other types.
+
 2015-07-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR c++/64079
index 47944f0..25cfa17 100644 (file)
@@ -2605,9 +2605,17 @@ is_reduction_operation_p (gimple stmt)
   gcc_assert (is_gimple_assign (stmt));
   code = gimple_assign_rhs_code (stmt);
 
-  return flag_associative_math
-    && commutative_tree_code (code)
-    && associative_tree_code (code);
+  if (!commutative_tree_code (code)
+      || !associative_tree_code (code))
+    return false;
+
+  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+
+  if (FLOAT_TYPE_P (type))
+    return flag_associative_math;
+
+  return (INTEGRAL_TYPE_P (type)
+         && TYPE_OVERFLOW_WRAPS (type));
 }
 
 /* Returns true when PHI contains an argument ARG.  */
index 57bb26d..56e1d81 100644 (file)
@@ -1,3 +1,18 @@
+2015-07-24  Tom de Vries  <tom@codesourcery.com>
+
+       * gcc.dg/graphite/block-1.c: Xfail scan.
+       * gcc.dg/graphite/interchange-12.c: Same.
+       * gcc.dg/graphite/interchange-14.c: Same.
+       * gcc.dg/graphite/interchange-15.c: Same.
+       * gcc.dg/graphite/interchange-9.c: Same.
+       * gcc.dg/graphite/interchange-mvt.c: Same.
+       * gcc.dg/graphite/uns-block-1.c: New test.
+       * gcc.dg/graphite/uns-interchange-12.c: New test.
+       * gcc.dg/graphite/uns-interchange-14.c: New test.
+       * gcc.dg/graphite/uns-interchange-15.c: New test.
+       * gcc.dg/graphite/uns-interchange-9.c: New test.
+       * gcc.dg/graphite/uns-interchange-mvt.c: New test.
+
 2015-07-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR c++/64079
index a73c20f..2208eb9 100644 (file)
@@ -45,4 +45,4 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "will be loop blocked" 3 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be loop blocked" 3 "graphite" { xfail *-*-* } } } */
index 41a8882..bf95fdd 100644 (file)
@@ -53,4 +53,4 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
index 36990ab..46f6a6d 100644 (file)
@@ -55,4 +55,4 @@ main (void)
 }
 
 /* PRE destroys the perfect nest and we can't cope with that yet.  */
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
index 3ddb74f..9f6b7ae 100644 (file)
@@ -49,5 +49,5 @@ main (void)
 }
 
 /* PRE destroys the perfect nest and we can't cope with that yet.  */
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
 
index cfec110..b023ea8 100644 (file)
@@ -44,4 +44,4 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
index 4b8f264..8c00f80 100644 (file)
@@ -59,5 +59,5 @@ main (void)
 }
 
 /* PRE destroys the perfect nest and we can't cope with that yet.  */
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
 
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-block-1.c b/gcc/testsuite/gcc.dg/graphite/uns-block-1.c
new file mode 100644 (file)
index 0000000..57d522b
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define MAX 100
+
+extern void abort ();
+
+int
+main (void)
+{
+  int i, j;
+  int sum = 0;
+  int A[MAX * MAX];
+  int B[MAX * MAX];
+
+  /* These loops should be loop blocked.  */
+  for (i = 0; i < MAX; i++)
+    for (j = 0; j < MAX; j++)
+      {
+       A[i*MAX + j] = j;
+       B[i*MAX + j] = j;
+      }
+
+  /* These loops should be loop blocked.  */
+  for (i = 0; i < MAX; i++)
+    for (j = 0; j < MAX; j++)
+      A[i*MAX + j] += B[j*MAX + i];
+
+  /* These loops should be loop blocked.  */
+  for (i = 0; i < MAX; i++)
+    for (j = 0; j < MAX; j++)
+      sum += A[i*MAX + j];
+
+#if DEBUG
+  fprintf (stderr, "sum = %d \n", sum);
+#endif
+
+  if (sum != 990000)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "will be loop blocked" 3 "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c
new file mode 100644 (file)
index 0000000..dc26926
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define N 200
+
+int A[N][N], B[N][N], C[N][N];
+
+static int __attribute__((noinline))
+matmult (void)
+{
+  int i, j, k;
+
+  /* Loops J and K should be interchanged.  */
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      {
+       A[i][j] = 0;
+       for (k = 0; k < N; k++)
+         A[i][j] += B[i][k] * C[k][j];
+      }
+
+  return A[0][0] + A[N-1][N-1];
+}
+
+extern void abort ();
+
+int
+main (void)
+{
+  int i, j, res;
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      {
+       A[i][j] = 0;
+       B[i][j] = i - j;
+       C[i][j] = i + j;
+      }
+
+  res = matmult ();
+
+#if DEBUG
+  fprintf (stderr, "res = %d \n", res);
+#endif
+
+  if (res != 2626800)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c
new file mode 100644 (file)
index 0000000..36990ab
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define N 200
+
+int A[N][N], B[N][N], C[N][N];
+
+static void __attribute__((noinline))
+matmult (void)
+{
+  int i, j, k;
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      A[i][j] = 0;
+
+  /* Loops J and K should be interchanged.  */
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      for (k = 0; k < N; k++)
+       A[i][j] += B[i][k] * C[k][j];
+}
+
+extern void abort ();
+
+int
+main (void)
+{
+  int i, j, res = 0;
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      {
+       B[i][j] = j;
+       C[i][j] = i;
+      }
+
+  matmult ();
+
+  for (i = 0; i < N; i++)
+    res += A[i][i];
+
+#if DEBUG
+  fprintf (stderr, "res = %d \n", res);
+#endif
+
+  if (res != 529340000)
+    abort ();
+
+  return 0;
+}
+
+/* PRE destroys the perfect nest and we can't cope with that yet.  */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c
new file mode 100644 (file)
index 0000000..3ddb74f
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define NMAX 2000
+
+static int x[NMAX], a[NMAX][NMAX];
+
+static int __attribute__((noinline))
+mvt (long N)
+{
+  int i,j;
+
+  /* These two loops should be interchanged.  */
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      x[i] += a[j][i];
+
+  return x[1];
+}
+
+extern void abort ();
+
+int
+main (void)
+{
+  int i, j, res;
+
+  for (i = 0; i < NMAX; i++)
+    for (j = 0; j < NMAX; j++)
+      a[i][j] = j;
+
+  for (i = 0; i < NMAX; i++)
+    x[i] = i;
+
+  res = mvt (NMAX);
+
+#if DEBUG
+  fprintf (stderr, "res = %d \n", res);
+#endif
+
+  if (res != 2001)
+    abort ();
+
+  return 0;
+}
+
+/* PRE destroys the perfect nest and we can't cope with that yet.  */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c
new file mode 100644 (file)
index 0000000..cfec110
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define N 111
+#define M 111
+
+static int __attribute__((noinline))
+foo (int *x)
+{
+  int i, j;
+  int sum = 0;
+
+  for (j = 0; j < M; ++j)
+    for (i = 0;  i < N; ++i)
+      sum += x[M * i + j];
+
+  return sum;
+}
+
+extern void abort ();
+
+int
+main (void)
+{
+  int A[N*M];
+  int i, res;
+
+  for (i = 0; i < N*M; i++)
+    A[i] = 2;
+
+  res = foo (A);
+
+#if DEBUG
+  fprintf (stderr, "res = %d \n", res);
+#endif
+
+  if (res != 24642)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c
new file mode 100644 (file)
index 0000000..4b8f264
--- /dev/null
@@ -0,0 +1,63 @@
+/* { dg-require-effective-target size32plus } */
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#endif
+
+#define NMAX 2000
+
+static int x1[NMAX], x2[NMAX], a[NMAX][NMAX], y1[NMAX], y2[NMAX];
+
+static int __attribute__((noinline))
+mvt (long N)
+{
+
+  int i,j;
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      x1[i] = x1[i] + a[i][j] * y1[j];
+
+  /* These two loops should be interchanged.  */
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      x2[i] = x2[i] + a[j][i] * y2[j];
+
+  return x1[0] + x2[0];
+}
+
+extern void abort ();
+
+int
+main (void)
+{
+  int i, j, res;
+
+  for (i = 0; i < NMAX; i++)
+    for (j = 0; j < NMAX; j++)
+      a[i][j] = i + j;
+
+  for (i = 0; i < NMAX; i++)
+    {
+      x1[i] = 0;
+      x2[i] = 2*i;
+      y1[i] = 100 - i;
+      y2[i] = i;
+    }
+
+  res = mvt (NMAX);
+
+#if DEBUG
+  fprintf (stderr, "res = %d \n", res);
+#endif
+
+  if (res != 199900000)
+    abort ();
+
+  return 0;
+}
+
+/* PRE destroys the perfect nest and we can't cope with that yet.  */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+