From: rguenth Date: Mon, 1 Sep 2008 13:39:42 +0000 (+0000) Subject: 2008-09-01 Richard Guenther X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=f1fb2997dc59523723f0cb73ea02cecf4e913021;p=pf3gnuchains%2Fgcc-fork.git 2008-09-01 Richard Guenther 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139864 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 078acdbc169..52c233c1440 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-09-01 Richard Guenther + + 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 * sel-sched-ir.c (cmp_v_in_regset_pool): Surround with diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f49a6ce31af..07830c86a4f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-09-01 Richard Guenther + + PR tree-optimization/37305 + * gcc.c-torture/compile/pr37305.c: New testcase. + 2008-09-01 Jakub Jelinek 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 00000000000..7c0673609df --- /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 870a244ac6d..9fe0753b1d9 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: