aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-reassoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r--gcc/tree-ssa-reassoc.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 60b4dae38a7..6bd52cca3d5 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2091,10 +2091,33 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
tree tem = build_range_check (loc, optype, exp, in_p, low, high);
enum warn_strict_overflow_code wc = WARN_STRICT_OVERFLOW_COMPARISON;
gimple_stmt_iterator gsi;
+ unsigned int uid;
if (tem == NULL_TREE)
return false;
+ /* If op is default def SSA_NAME, there is no place to insert the
+ new comparison. Give up, unless we can use OP itself as the
+ range test. */
+ if (op && SSA_NAME_IS_DEFAULT_DEF (op))
+ {
+ if (op == range->exp
+ && ((TYPE_PRECISION (optype) == 1 && TYPE_UNSIGNED (optype))
+ || TREE_CODE (optype) == BOOLEAN_TYPE)
+ && (op == tem
+ || (TREE_CODE (tem) == EQ_EXPR
+ && TREE_OPERAND (tem, 0) == op
+ && integer_onep (TREE_OPERAND (tem, 1))))
+ && opcode != BIT_IOR_EXPR
+ && (opcode != ERROR_MARK || oe->rank != BIT_IOR_EXPR))
+ {
+ stmt = NULL;
+ tem = op;
+ }
+ else
+ return false;
+ }
+
if (strict_overflow_p && issue_strict_overflow_warning (wc))
warning_at (loc, OPT_Wstrict_overflow,
"assuming signed overflow does not occur "
@@ -2128,11 +2151,22 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
tem = invert_truthvalue_loc (loc, tem);
tem = fold_convert_loc (loc, optype, tem);
- gsi = gsi_for_stmt (stmt);
+ if (stmt)
+ {
+ gsi = gsi_for_stmt (stmt);
+ uid = gimple_uid (stmt);
+ }
+ else
+ {
+ gsi = gsi_none ();
+ uid = 0;
+ }
+ if (stmt == NULL)
+ gcc_checking_assert (tem == op);
/* In rare cases range->exp can be equal to lhs of stmt.
In that case we have to insert after the stmt rather then before
it. */
- if (op == range->exp)
+ else if (op == range->exp)
tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, false,
GSI_CONTINUE_LINKING);
else
@@ -2145,7 +2179,7 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
if (gimple_uid (gsi_stmt (gsi)))
break;
else
- gimple_set_uid (gsi_stmt (gsi), gimple_uid (stmt));
+ gimple_set_uid (gsi_stmt (gsi), uid);
oe->op = tem;
range->exp = exp;