diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 682e11f2308..5ae727b8374 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-04-16 Richard Guenther + + PR tree-optimization/52975 + * tree-ssa-forwprop.c (combine_cond_exprs): New function. + (ssa_forward_propagate_and_combine): Call it for COND_EXPRs + and VEC_COND_EXPRs. Also combine into VEC_COND_EXPRs condition. + * fold-const.c (operand_equal_p): Handle TARGET_MEM_REF. + 2012-04-14 Uros Bizjak * config/i386/sse.md (ssse3_plusminus): New code iterator. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index dcd64a08a1b..8aceb733e7d 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2562,6 +2562,14 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case IMAGPART_EXPR: return OP_SAME (0); + case TARGET_MEM_REF: + /* Require equal extra operands and then fall thru to MEM_REF + handling of the two common operands. */ + if (!OP_SAME_WITH_NULL (2) + || !OP_SAME_WITH_NULL (3) + || !OP_SAME_WITH_NULL (4)) + return 0; + /* Fallthru. */ case MEM_REF: /* Require equal access sizes, and similar pointer types. We can have incomplete types for array references of diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 57b93cee7f1..3e2371bc83c 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -632,6 +632,58 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) return 0; } +/* Propagate from the ssa name definition statements of COND_EXPR + values in the rhs of statement STMT into the conditional arms + if that simplifies it. + Returns true if the stmt was changed. */ + +static bool +combine_cond_exprs (gimple_stmt_iterator *gsi_p) +{ + gimple stmt = gsi_stmt (*gsi_p); + tree cond, val1, val2; + bool changed = false; + + cond = gimple_assign_rhs1 (stmt); + val1 = gimple_assign_rhs2 (stmt); + if (TREE_CODE (val1) == SSA_NAME) + { + gimple def_stmt = SSA_NAME_DEF_STMT (val1); + if (is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt) + && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0)) + { + val1 = unshare_expr (gimple_assign_rhs2 (def_stmt)); + gimple_assign_set_rhs2 (stmt, val1); + changed = true; + } + } + val2 = gimple_assign_rhs3 (stmt); + if (TREE_CODE (val2) == SSA_NAME) + { + gimple def_stmt = SSA_NAME_DEF_STMT (val2); + if (is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt) + && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0)) + { + val2 = unshare_expr (gimple_assign_rhs3 (def_stmt)); + gimple_assign_set_rhs3 (stmt, val2); + changed = true; + } + } + if (operand_equal_p (val1, val2, 0)) + { + gimple_assign_set_rhs_from_tree (gsi_p, val1); + stmt = gsi_stmt (*gsi_p); + changed = true; + } + + if (changed) + update_stmt (stmt); + + return changed; +} + /* We've just substituted an ADDR_EXPR into stmt. Update all the relevant data structures to match. */ @@ -2480,10 +2532,12 @@ ssa_forward_propagate_and_combine (void) || code == NEGATE_EXPR) && TREE_CODE (rhs1) == SSA_NAME) changed = simplify_not_neg_expr (&gsi); - else if (code == COND_EXPR) + else if (code == COND_EXPR + || code == VEC_COND_EXPR) { /* In this case the entire COND_EXPR is in rhs1. */ changed |= forward_propagate_into_cond (&gsi); + changed |= combine_cond_exprs (&gsi); stmt = gsi_stmt (gsi); } else if (TREE_CODE_CLASS (code) == tcc_comparison)