This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR42326: convert expressions in chrec_fold_plus
- From: Sebastian Pop <sebpop at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 5 Mar 2010 06:16:40 -0600
- Subject: [patch] Fix PR42326: convert expressions in chrec_fold_plus
Hi,
The problem in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42326 is
that we currently do not handle correctly convert expressions in
chrec_fold_{plus,multiply}: for now we consider that a convert
expression does not contain any evolution in any loop, and this leads
to scevs that have no defined semantics: for example, when
op0 = (integer(kind=4)) {0, +, 1}_4 gets added to op1 = {0, +, 1}_1,
the result is: {(integer(kind=4)) {0, +, 1}_4, +, 1}_1
the initial value of the result variates in loop_4 but that loop is
contained in loop_1.
The solution for now is to avoid these cases. This patch passed
make -k check RUNTESTFLAGS=tree-ssa.exp, graphite.exp and vect.exp on
both amd64-linux and i686-linux. I am now bootstraping and testing
the attached patch on i686-linux and amd64-linux.
Sebastian Pop
--
AMD / Open Source Compiler Engineering / GNU Tools
From 860461cfb86ec362d2776932f2db614f5d08f933 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <sebpop@gmail.com>
Date: Fri, 5 Mar 2010 05:49:48 -0600
Subject: [PATCH] Fix PR42326: Handle more carefully convert expressions in chrec_fold_plus and chrec_fold_mult.
2010-03-05 Sebastian Pop <sebastian.pop@amd.com>
PR middle-end/42326
* tree-chrec.c (chrec_fold_plus_1): Do not handle convert expressions
that contain scevs.
(chrec_fold_multiply): Same.
* gfortran.dg/graphite/pr42326.f90: New.
* gfortran.dg/graphite/pr42326-1.f90: New.
---
gcc/testsuite/gfortran.dg/graphite/pr42326-1.f90 | 16 ++++++++++
gcc/testsuite/gfortran.dg/graphite/pr42326.f90 | 33 ++++++++++++++++++++++
gcc/tree-chrec.c | 24 ++++++++++++++++
3 files changed, 73 insertions(+), 0 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/graphite/pr42326-1.f90
create mode 100644 gcc/testsuite/gfortran.dg/graphite/pr42326.f90
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42326-1.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42326-1.f90
new file mode 100644
index 0000000..8163fd4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/pr42326-1.f90
@@ -0,0 +1,16 @@
+! { dg-options "-O2 -floop-parallelize-all -fprefetch-loop-arrays" }
+
+subroutine phasad(t,i,ium)
+ implicit none
+ real t(5,4)
+ integer i,l,ll,ium
+
+ do l=1,2
+ ll=2*l
+ do i=1,ium
+ t(i,ll-1)=t(i,ll-1)+t(i,ll)
+ enddo
+ enddo
+ return
+end subroutine phasad
+
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42326.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42326.f90
new file mode 100644
index 0000000..c603a6e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/pr42326.f90
@@ -0,0 +1,33 @@
+! { dg-options "-O2 -floop-strip-mine -fprefetch-loop-arrays" }
+
+subroutine blts ( ldmx, ldmy, v, tmp1, i, j, k)
+ implicit none
+ integer ldmx, ldmy, i, j, k, ip, m, l
+ real*8 tmp, tmp1, v( 5, ldmx, ldmy, *), tmat(5,5)
+
+ do ip = 1, 4
+ do m = ip+1, 5
+ tmp = tmp1 * tmat( m, ip )
+ do l = ip+1, 5
+ tmat( m, l ) = tmat( m, l ) - tmat( ip, l )
+ end do
+ v( m, i, j, k ) = tmp
+ end do
+ end do
+ return
+end subroutine blts
+
+subroutine phasad(t,i,ium)
+ implicit none
+ real t(5,4)
+ integer i,l,ll,ium
+
+ do l=1,2
+ ll=2*l
+ do i=1,ium
+ t(i,ll-1)=t(i,ll-1)+t(i,ll)
+ enddo
+ enddo
+ return
+end subroutine phasad
+
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 18ed4ed..c945f93 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -283,6 +283,10 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
case POLYNOMIAL_CHREC:
return chrec_fold_plus_poly_poly (code, type, op0, op1);
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op1, NULL))
+ return chrec_dont_know;
+
default:
if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
return build_polynomial_chrec
@@ -296,6 +300,10 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
CHREC_RIGHT (op0));
}
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op0, NULL))
+ return chrec_dont_know;
+
default:
switch (TREE_CODE (op1))
{
@@ -314,6 +322,10 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
? build_real (type, dconstm1)
: build_int_cst_type (type, -1)));
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op1, NULL))
+ return chrec_dont_know;
+
default:
{
int size = 0;
@@ -393,6 +405,10 @@ chrec_fold_multiply (tree type,
case POLYNOMIAL_CHREC:
return chrec_fold_multiply_poly_poly (type, op0, op1);
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op1, NULL))
+ return chrec_dont_know;
+
default:
if (integer_onep (op1))
return op0;
@@ -405,6 +421,10 @@ chrec_fold_multiply (tree type,
chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));
}
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op0, NULL))
+ return chrec_dont_know;
+
default:
if (integer_onep (op0))
return op1;
@@ -420,6 +440,10 @@ chrec_fold_multiply (tree type,
chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
chrec_fold_multiply (type, CHREC_RIGHT (op1), op0));
+ CASE_CONVERT:
+ if (tree_contains_chrecs (op1, NULL))
+ return chrec_dont_know;
+
default:
if (integer_onep (op1))
return op0;
--
1.6.3.3