aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-scalar-evolution.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-06-27 11:32:30 +0000
committerRichard Guenther <rguenther@suse.de>2012-06-27 11:32:30 +0000
commit107ec6080783cabaa1968d5c1d7c241218bc49b7 (patch)
treed0a3413286a82915919c9aaf8c25c24327aaa711 /gcc/tree-scalar-evolution.c
parent755090ed518c9000fb184582a98bda63e998064f (diff)
2012-06-27 Richard Guenther <rguenther@suse.de>
PR middle-end/53676 * tree-chrec.c (chrec_convert_1): Represent truncation to a type with undefined overflow as truncation to an unsigned type converted to the type with undefined overflow. * tree-scalar-evolution.c (interpret_rhs_expr): For computing the scalar evolution of a truncated widened operation avoid looking at the non-existing evolution of the widened operation result. * gcc.dg/tree-ssa/scev-6.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@189013 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-scalar-evolution.c')
-rw-r--r--gcc/tree-scalar-evolution.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 21d1fd0a4a1..486197e88a7 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1634,6 +1634,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
tree type, tree rhs1, enum tree_code code, tree rhs2)
{
tree res, chrec1, chrec2;
+ gimple def;
if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
{
@@ -1759,7 +1760,29 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
break;
CASE_CONVERT:
- chrec1 = analyze_scalar_evolution (loop, rhs1);
+ /* In case we have a truncation of a widened operation that in
+ the truncated type has undefined overflow behavior analyze
+ the operation done in an unsigned type of the same precision
+ as the final truncation. We cannot derive a scalar evolution
+ for the widened operation but for the truncated result. */
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (rhs1)) == INTEGER_TYPE
+ && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (rhs1))
+ && TYPE_OVERFLOW_UNDEFINED (type)
+ && TREE_CODE (rhs1) == SSA_NAME
+ && (def = SSA_NAME_DEF_STMT (rhs1))
+ && is_gimple_assign (def)
+ && TREE_CODE_CLASS (gimple_assign_rhs_code (def)) == tcc_binary
+ && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+ {
+ tree utype = unsigned_type_for (type);
+ chrec1 = interpret_rhs_expr (loop, at_stmt, utype,
+ gimple_assign_rhs1 (def),
+ gimple_assign_rhs_code (def),
+ gimple_assign_rhs2 (def));
+ }
+ else
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
res = chrec_convert (type, chrec1, at_stmt);
break;