diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-27 11:32:30 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-27 11:32:30 +0000 |
commit | 3ef23449da3010c846c29b78e00dc0ecd0bbbcda (patch) | |
tree | d0a3413286a82915919c9aaf8c25c24327aaa711 /gcc/tree-scalar-evolution.c | |
parent | 61e371b02721334c7cea01ec16f68bb4ce4358df (diff) | |
download | gcc-3ef23449da3010c846c29b78e00dc0ecd0bbbcda.tar.gz |
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: svn+ssh://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.c | 25 |
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; |