diff options
author | Richard Guenther <rguenther@suse.de> | 2008-09-01 13:39:42 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-09-01 13:39:42 +0000 |
commit | ff8b183bbbf3de4d4447b5ff5825717c5b92cc87 (patch) | |
tree | b6def91a807329a8ca74f2bc4a22570463460d0a | |
parent | 68ad446f149f501726ac386f64add454ac37e342 (diff) | |
download | gcc-ff8b183bbbf3de4d4447b5ff5825717c5b92cc87.zip gcc-ff8b183bbbf3de4d4447b5ff5825717c5b92cc87.tar.gz gcc-ff8b183bbbf3de4d4447b5ff5825717c5b92cc87.tar.bz2 |
re PR tree-optimization/37305 (ice in set_value_range, at tree-vrp.c:397)
2008-09-01 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37305
* tree-ssa-ccp.c (ccp_fold): Do not set TREE_OVERFLOW on
the result of constant conversions.
(fold_gimple_assign): Likewise.
* gcc.c-torture/compile/pr37305.c: New testcase.
From-SVN: r139864
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr37305.c | 19 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 67 |
4 files changed, 77 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 078acdb..52c233c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-09-01 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/37305 + * tree-ssa-ccp.c (ccp_fold): Do not set TREE_OVERFLOW on + the result of constant conversions. + (fold_gimple_assign): Likewise. + 2008-09-01 Andrey Belevantsev <abel@ispras.ru> * sel-sched-ir.c (cmp_v_in_regset_pool): Surround with diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f49a6ce..07830c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-09-01 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/37305 + * gcc.c-torture/compile/pr37305.c: New testcase. + 2008-09-01 Jakub Jelinek <jakub@redhat.com> PR middle-end/36449 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37305.c b/gcc/testsuite/gcc.c-torture/compile/pr37305.c new file mode 100644 index 0000000..7c06736 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr37305.c @@ -0,0 +1,19 @@ +typedef int int32_t; +typedef unsigned int uint32_t; +static inline int +safe_add_s_s (int si1, int si2) +{ + if ((si1 > 0) && (si2 > 0) && (si1 > (si2)) || (si1 < 0) && (si2 < 0) + && (si1 < ((-__INT_MAX__ - 1) - si2))) + return si1; +} + +uint32_t g_8; +uint32_t +func_24 (int32_t p_25) +{ + uint32_t l_30 = -1L; + if ((safe_mod_u_u (1, 1)) | (safe_add_s_s (g_8, l_30))) + return 1; +} + diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 870a244..9fe0753 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -941,6 +941,7 @@ ccp_fold (gimple stmt) so this should almost always return a simplified RHS. */ tree lhs = gimple_assign_lhs (stmt); tree op0 = gimple_assign_rhs1 (stmt); + tree res; /* Simplify the operand down to a constant. */ if (TREE_CODE (op0) == SSA_NAME) @@ -976,8 +977,21 @@ ccp_fold (gimple stmt) return op0; } - return fold_unary (subcode, gimple_expr_type (stmt), op0); - } + res = fold_unary (subcode, gimple_expr_type (stmt), op0); + + /* If the operation was a conversion do _not_ mark a + resulting constant with TREE_OVERFLOW if the original + constant was not. These conversions have implementation + defined behavior and retaining the TREE_OVERFLOW flag + here would confuse later passes such as VRP. */ + if (res + && TREE_CODE (res) == INTEGER_CST + && TREE_CODE (op0) == INTEGER_CST + && CONVERT_EXPR_CODE_P (subcode)) + TREE_OVERFLOW (res) = TREE_OVERFLOW (op0); + + return res; + } case GIMPLE_BINARY_RHS: { @@ -2644,26 +2658,37 @@ fold_gimple_assign (gimple_stmt_iterator *si) break; case GIMPLE_UNARY_RHS: - result = fold_unary (subcode, - gimple_expr_type (stmt), - gimple_assign_rhs1 (stmt)); + { + tree rhs = gimple_assign_rhs1 (stmt); - if (result) - { - STRIP_USELESS_TYPE_CONVERSION (result); - if (valid_gimple_rhs_p (result)) - return result; - } - else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)) - && POINTER_TYPE_P (gimple_expr_type (stmt)) - && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))) - { - tree type = gimple_expr_type (stmt); - tree t = maybe_fold_offset_to_address (gimple_assign_rhs1 (stmt), - integer_zero_node, type); - if (t) - return t; - } + result = fold_unary (subcode, gimple_expr_type (stmt), rhs); + if (result) + { + /* If the operation was a conversion do _not_ mark a + resulting constant with TREE_OVERFLOW if the original + constant was not. These conversions have implementation + defined behavior and retaining the TREE_OVERFLOW flag + here would confuse later passes such as VRP. */ + if (CONVERT_EXPR_CODE_P (subcode) + && TREE_CODE (result) == INTEGER_CST + && TREE_CODE (rhs) == INTEGER_CST) + TREE_OVERFLOW (result) = TREE_OVERFLOW (rhs); + + STRIP_USELESS_TYPE_CONVERSION (result); + if (valid_gimple_rhs_p (result)) + return result; + } + else if (CONVERT_EXPR_CODE_P (subcode) + && POINTER_TYPE_P (gimple_expr_type (stmt)) + && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))) + { + tree type = gimple_expr_type (stmt); + tree t = maybe_fold_offset_to_address (gimple_assign_rhs1 (stmt), + integer_zero_node, type); + if (t) + return t; + } + } break; case GIMPLE_BINARY_RHS: |