From e6df850973c9cc688cad4d9bff4c1260c028025d Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Fri, 24 Jul 2015 20:55:22 +0000 Subject: [PATCH] Don't allow unsafe reductions in graphite 2015-07-24 Tom de Vries * 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 --- gcc/ChangeLog | 6 ++ gcc/graphite-sese-to-poly.c | 14 ++++- gcc/testsuite/ChangeLog | 15 +++++ gcc/testsuite/gcc.dg/graphite/block-1.c | 2 +- .../gcc.dg/graphite/interchange-12.c | 2 +- .../gcc.dg/graphite/interchange-14.c | 2 +- .../gcc.dg/graphite/interchange-15.c | 2 +- gcc/testsuite/gcc.dg/graphite/interchange-9.c | 2 +- .../gcc.dg/graphite/interchange-mvt.c | 2 +- gcc/testsuite/gcc.dg/graphite/uns-block-1.c | 48 ++++++++++++++ .../gcc.dg/graphite/uns-interchange-12.c | 56 +++++++++++++++++ .../gcc.dg/graphite/uns-interchange-14.c | 58 +++++++++++++++++ .../gcc.dg/graphite/uns-interchange-15.c | 53 ++++++++++++++++ .../gcc.dg/graphite/uns-interchange-9.c | 47 ++++++++++++++ .../gcc.dg/graphite/uns-interchange-mvt.c | 63 +++++++++++++++++++ 15 files changed, 363 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-block-1.c create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c create mode 100644 gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 264570832f7..3bd8ff1a869 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-07-24 Tom de Vries + + * 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 PR c++/64079 diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 47944f0c3ee..25cfa17b948 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 57bb26d014e..56e1d81ffa4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2015-07-24 Tom de Vries + + * 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 PR c++/64079 diff --git a/gcc/testsuite/gcc.dg/graphite/block-1.c b/gcc/testsuite/gcc.dg/graphite/block-1.c index a73c20fd616..2208eb9d16b 100644 --- a/gcc/testsuite/gcc.dg/graphite/block-1.c +++ b/gcc/testsuite/gcc.dg/graphite/block-1.c @@ -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 *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-12.c b/gcc/testsuite/gcc.dg/graphite/interchange-12.c index 41a8882fbfb..bf95fdd98ad 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-12.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-12.c @@ -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 *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-14.c b/gcc/testsuite/gcc.dg/graphite/interchange-14.c index 36990ab40fd..46f6a6deb23 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-14.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-14.c @@ -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 *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-15.c b/gcc/testsuite/gcc.dg/graphite/interchange-15.c index 3ddb74f0407..9f6b7aeda44 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-15.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-15.c @@ -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 *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-9.c b/gcc/testsuite/gcc.dg/graphite/interchange-9.c index cfec1100eee..b023ea8a907 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-9.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-9.c @@ -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 *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c b/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c index 4b8f2646bef..8c00f8073ef 100644 --- a/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c +++ b/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c @@ -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 index 00000000000..57d522b2842 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-block-1.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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 index 00000000000..dc269266977 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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 index 00000000000..36990ab40fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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 index 00000000000..3ddb74f0407 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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 index 00000000000..cfec1100eee --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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 index 00000000000..4b8f2646bef --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c @@ -0,0 +1,63 @@ +/* { dg-require-effective-target size32plus } */ + +#define DEBUG 0 +#if DEBUG +#include +#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" } } */ + -- 2.30.2