diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-03 14:11:14 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-03 14:11:14 +0000 |
commit | b5a4c0720f2d5d2245ec7a2a72f157b4975a9b6e (patch) | |
tree | da07aebd6bf18cfc4b02509b36bbfa4e25280ee9 /gcc/tree-chrec.c | |
parent | b18878555c397f5aab203df348bfa33d114ee242 (diff) | |
download | gcc-b5a4c0720f2d5d2245ec7a2a72f157b4975a9b6e.tar.gz |
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.
* gfortran.dg/pr34163.f90: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149207 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-chrec.c')
-rw-r--r-- | gcc/tree-chrec.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 997ce893593..74935043918 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)) |