aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr34163.f9016
-rw-r--r--gcc/tree-chrec.c15
5 files changed, 44 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c2655c8..493d1b2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2009-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34163
+ * tree-chrec.c (chrec_convert_1): Fold (T2)(t +- x) to
+ (T2)t +- (T2)x if t +- x is known to not overflow and
+ the conversion widens the operation.
+ * Makefile.in (tree-chrec.o): Add $(FLAGS_H) dependency.
+
2009-07-03 Jan Hubicka <jh@suse.cz>
* ipa-pure-const.c (analyze): Update loop optimizer init.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index c196aca..9901d07 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2414,7 +2414,7 @@ omega.o : omega.c omega.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) $(TREE_H) $(DIAGNOSTIC_H) varray.h $(TREE_PASS_H) $(PARAMS_H)
tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) $(TREE_H) $(REAL_H) $(SCEV_H) $(TREE_PASS_H) $(PARAMS_H) \
- $(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H)
+ $(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(FLAGS_H)
tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \
$(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 42a5374..b739808 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34163
+ * gfortran.dg/pr34163.f90: New testcase.
+
2009-07-03 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/loop-24.c: Update dump file matching; enable -O2.
diff --git a/gcc/testsuite/gfortran.dg/pr34163.f90 b/gcc/testsuite/gfortran.dg/pr34163.f90
new file mode 100644
index 0000000..6426177
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr34163.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-options "-O2 -fpredictive-commoning -fdump-tree-pcom-details" }
+subroutine trisolve2(x,i1,i2,nxyz)
+integer :: nxyz
+real,dimension(nxyz):: au1
+real,allocatable,dimension(:) :: gi
+integer :: i1 , i2
+real,dimension(i2)::x
+integer :: i
+allocate(gi(nxyz))
+do i = i1+1 , i2
+ x(i) = gi(i)*(x(i)-au1(i-1)*x(i-1))
+enddo
+end subroutine trisolve2
+! { dg-final { scan-tree-dump "Executing predictive commoning" "pcom" } }
+! { dg-final { cleanup-tree-dump "pcom" } }
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 997ce89..7493504 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-chrec.h"
#include "tree-pass.h"
#include "params.h"
+#include "flags.h"
#include "tree-scalar-evolution.h"
@@ -1286,7 +1287,19 @@ chrec_convert_1 (tree type, tree chrec, gimple at_stmt,
/* If we cannot propagate the cast inside the chrec, just keep the cast. */
keep_cast:
- res = fold_convert (type, chrec);
+ /* Fold will not canonicalize (long)(i - 1) to (long)i - 1 because that
+ may be more expensive. We do want to perform this optimization here
+ though for canonicalization reasons. */
+ if (use_overflow_semantics
+ && (TREE_CODE (chrec) == PLUS_EXPR
+ || TREE_CODE (chrec) == MINUS_EXPR)
+ && TYPE_PRECISION (type) > TYPE_PRECISION (ct)
+ && TYPE_OVERFLOW_UNDEFINED (ct))
+ res = fold_build2 (TREE_CODE (chrec), type,
+ fold_convert (type, TREE_OPERAND (chrec, 0)),
+ fold_convert (type, TREE_OPERAND (chrec, 1)));
+ else
+ res = fold_convert (type, chrec);
/* Don't propagate overflows. */
if (CONSTANT_CLASS_P (res))