diff options
author | Tom de Vries <tom@codesourcery.com> | 2015-07-24 20:55:22 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2015-07-24 20:55:22 +0000 |
commit | e6df850973c9cc688cad4d9bff4c1260c028025d (patch) | |
tree | 4b8350baf0dc6269f524db5a85b88dd0a48113aa /gcc | |
parent | 274d8c11f37abd11a3a43b5bd129c194b0daeafc (diff) | |
download | gcc-e6df850973c9cc688cad4d9bff4c1260c028025d.zip gcc-e6df850973c9cc688cad4d9bff4c1260c028025d.tar.gz gcc-e6df850973c9cc688cad4d9bff4c1260c028025d.tar.bz2 |
Don't allow unsafe reductions in graphite
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/graphite-sese-to-poly.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/block-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/interchange-12.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/interchange-14.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/interchange-15.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/interchange-9.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/interchange-mvt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-block-1.c | 48 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-interchange-12.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-interchange-14.c | 58 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-interchange-9.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c | 63 |
15 files changed, 363 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2645708..3bd8ff1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 47944f0..25cfa17 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 57bb26d..56e1d81 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/graphite/block-1.c b/gcc/testsuite/gcc.dg/graphite/block-1.c index a73c20f..2208eb9 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 41a8882..bf95fdd 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 36990ab..46f6a6d 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 3ddb74f..9f6b7ae 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 cfec110..b023ea8 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 4b8f264..8c00f80 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 0000000..57d522b --- /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 <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 index 0000000..dc26926 --- /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 <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 index 0000000..36990ab --- /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 <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 index 0000000..3ddb74f --- /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 <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 index 0000000..cfec110 --- /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 <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 index 0000000..4b8f264 --- /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 <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" } } */ + |