gimple stmt = gsi_stmt (*gsi);
tree tmp;
bool cfg_changed = false;
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs2 = gimple_assign_rhs2 (stmt);
/* Combine the comparison with defining statements. */
tmp = forward_propagate_into_comparison_1 (stmt,
gimple_assign_rhs_code (stmt),
- TREE_TYPE
- (gimple_assign_lhs (stmt)),
- rhs1, rhs2);
- if (tmp)
+ type, rhs1, rhs2);
+ if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp)))
{
gimple_assign_set_rhs_from_tree (gsi, tmp);
fold_stmt (gsi);
}
}
- if (tmp)
+ if (tmp
+ && is_gimple_condexpr (tmp))
{
if (dump_file && tmp)
{
&& ((rhs_code == SSA_NAME && rhs == name)
|| CONVERT_EXPR_CODE_P (rhs_code)))
{
- /* Don't propagate restrict pointer's RHS. */
- if (TYPE_RESTRICT (TREE_TYPE (lhs))
- && !TYPE_RESTRICT (TREE_TYPE (name))
- && !is_gimple_min_invariant (def_rhs))
- return false;
/* Only recurse if we don't deal with a single use or we cannot
do the propagation to the current statement. In particular
we can end up with a conversion needed for a non-invariant
that of the pointed-to type of the address we can put the
dereferenced address on the LHS preserving the original alias-type. */
else if (gimple_assign_lhs (use_stmt) == lhs
+ && integer_zerop (TREE_OPERAND (lhs, 1))
&& useless_type_conversion_p
(TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
{
tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
- tree new_offset, new_base, saved;
+ tree new_offset, new_base, saved, new_lhs;
while (handled_component_p (*def_rhs_basep))
def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
saved = *def_rhs_basep;
if (TREE_CODE (*def_rhs_basep) == MEM_REF)
{
new_base = TREE_OPERAND (*def_rhs_basep, 0);
- new_offset
- = int_const_binop (PLUS_EXPR, TREE_OPERAND (lhs, 1),
- TREE_OPERAND (*def_rhs_basep, 1));
+ new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),
+ TREE_OPERAND (*def_rhs_basep, 1));
}
else
{
*def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
new_base, new_offset);
TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs);
+ TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs);
TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
- gimple_assign_set_lhs (use_stmt,
- unshare_expr (TREE_OPERAND (def_rhs, 0)));
+ new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ gimple_assign_set_lhs (use_stmt, new_lhs);
+ TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
+ TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs);
*def_rhs_basep = saved;
tidy_after_forward_propagate_addr (use_stmt);
/* Continue propagating into the RHS if this was not the
that of the pointed-to type of the address we can put the
dereferenced address on the RHS preserving the original alias-type. */
else if (gimple_assign_rhs1 (use_stmt) == rhs
+ && integer_zerop (TREE_OPERAND (rhs, 1))
&& useless_type_conversion_p
(TREE_TYPE (gimple_assign_lhs (use_stmt)),
TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
{
tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
- tree new_offset, new_base, saved;
+ tree new_offset, new_base, saved, new_rhs;
while (handled_component_p (*def_rhs_basep))
def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
saved = *def_rhs_basep;
if (TREE_CODE (*def_rhs_basep) == MEM_REF)
{
new_base = TREE_OPERAND (*def_rhs_basep, 0);
- new_offset
- = int_const_binop (PLUS_EXPR, TREE_OPERAND (rhs, 1),
- TREE_OPERAND (*def_rhs_basep, 1));
+ new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),
+ TREE_OPERAND (*def_rhs_basep, 1));
}
else
{
*def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
new_base, new_offset);
TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
+ TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
- gimple_assign_set_rhs1 (use_stmt,
- unshare_expr (TREE_OPERAND (def_rhs, 0)));
+ new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ gimple_assign_set_rhs1 (use_stmt, new_rhs);
+ TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
+ TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs);
*def_rhs_basep = saved;
fold_stmt_inplace (use_stmt_gsi);
tidy_after_forward_propagate_addr (use_stmt);
if (!is_gimple_val (ptr1))
ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
true, GSI_SAME_STMT);
- gimple_call_set_fndecl (stmt2, built_in_decls [BUILT_IN_MEMCPY]);
+ gimple_call_set_fndecl (stmt2,
+ builtin_decl_explicit (BUILT_IN_MEMCPY));
gimple_call_set_arg (stmt2, 0, ptr1);
gimple_call_set_arg (stmt2, 1, new_str_cst);
gimple_call_set_arg (stmt2, 2,
unsigned int final_prec = TYPE_PRECISION (type);
int final_unsignedp = TYPE_UNSIGNED (type);
+ /* Don't propagate ssa names that occur in abnormal phis. */
+ if (TREE_CODE (defop0) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (defop0))
+ return 0;
+
/* In addition to the cases of two conversions in a row
handled below, if we are converting something to its own
type via an object of identical or wider precision, neither