}
}
/* If there was an UNDEFINED operand but the result may be not UNDEFINED
- fall back to VARYING even if there were CONSTANT operands. */
+ fall back to CONSTANT. During iteration UNDEFINED may still drop
+ to CONSTANT. */
if (has_undefined_operand)
- return VARYING;
+ return CONSTANT;
/* We do not consider virtual operands here -- load from read-only
memory may have only VARYING virtual operands, but still be
prop_value_t rval = get_value_for_expr (rhs, true);
double_int value, mask;
prop_value_t val;
+
+ if (rval.lattice_val == UNDEFINED)
+ return rval;
+
gcc_assert ((rval.lattice_val == CONSTANT
&& TREE_CODE (rval.value) == INTEGER_CST)
|| double_int_minus_one_p (rval.mask));
prop_value_t r2val = get_value_for_expr (rhs2, true);
double_int value, mask;
prop_value_t val;
+
+ if (r1val.lattice_val == UNDEFINED
+ || r2val.lattice_val == UNDEFINED)
+ {
+ val.lattice_val = VARYING;
+ val.value = NULL_TREE;
+ val.mask = double_int_minus_one;
+ return val;
+ }
+
gcc_assert ((r1val.lattice_val == CONSTANT
&& TREE_CODE (r1val.value) == INTEGER_CST)
|| double_int_minus_one_p (r1val.mask));
}
/* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert
- a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. */
+ a clobber of VAR before each matching BUILT_IN_STACK_RESTORE.
+
+ It is possible that BUILT_IN_STACK_SAVE cannot be find in a dominator when a
+ previous pass (such as DOM) duplicated it along multiple paths to a BB. In
+ that case the function gives up without inserting the clobbers. */
static void
insert_clobbers_for_var (gimple_stmt_iterator i, tree var)
{
- bool save_found;
gimple stmt;
tree saved_val;
htab_t visited = NULL;
- for (save_found = false; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i))
+ for (; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i))
{
stmt = gsi_stmt (i);
if (!gimple_call_builtin_p (stmt, BUILT_IN_STACK_SAVE))
continue;
- save_found = true;
saved_val = gimple_call_lhs (stmt);
if (saved_val == NULL_TREE)
if (visited != NULL)
htab_delete (visited);
- gcc_assert (save_found);
}
/* Detects a __builtin_alloca_with_align with constant size argument. Declares
case BUILT_IN_VA_START:
if (!va_list_simple_ptr
|| targetm.expand_builtin_va_start != NULL
- || builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
+ || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
return NULL_TREE;
if (gimple_call_num_args (call) != 2)