aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-09-01 13:39:42 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-09-01 13:39:42 +0000
commitff8b183bbbf3de4d4447b5ff5825717c5b92cc87 (patch)
treeb6def91a807329a8ca74f2bc4a22570463460d0a
parent68ad446f149f501726ac386f64add454ac37e342 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37305.c19
-rw-r--r--gcc/tree-ssa-ccp.c67
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: