When looking at the code we produce from if-conversion and vectorization
I noticed several things.  For one, we are not handling TARGET_MEM_REF
in operand_equal_p which means that DOM does not clean up loads/stores
of that form (to the extent DOM can do that anyway).  Also we never
simplify the conditions in VEC_COND_EXPRs because the combining in
forwprop does not handle them.  And we do not combine the inverted
COND_EXPRs if-conversion can create - but it's easy to do that in 
forwprop.

The following addresses this two issues.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-04-16  Richard Guenther  <rguent...@suse.de>

        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.

Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c     (revision 186417)
--- gcc/tree-ssa-forwprop.c     (working copy)
*************** forward_propagate_into_cond (gimple_stmt
*** 632,637 ****
--- 632,689 ----
    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.  */
  
*************** ssa_forward_propagate_and_combine (void)
*** 2480,2489 ****
                     || code == NEGATE_EXPR)
                    && TREE_CODE (rhs1) == SSA_NAME)
                  changed = simplify_not_neg_expr (&gsi);
!               else if (code == COND_EXPR)
                  {
                    /* In this case the entire COND_EXPR is in rhs1. */
                    changed |= forward_propagate_into_cond (&gsi);
                    stmt = gsi_stmt (gsi);
                  }
                else if (TREE_CODE_CLASS (code) == tcc_comparison)
--- 2532,2543 ----
                     || code == NEGATE_EXPR)
                    && TREE_CODE (rhs1) == SSA_NAME)
                  changed = simplify_not_neg_expr (&gsi);
!               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)
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c    (revision 186417)
--- gcc/fold-const.c    (working copy)
*************** operand_equal_p (const_tree arg0, const_
*** 2562,2567 ****
--- 2562,2575 ----
        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

Reply via email to