2011-09-07 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Sep 2011 13:02:05 +0000 (13:02 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Sep 2011 13:02:05 +0000 (13:02 +0000)
* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
Canonicalize negated predicates by swapping edges.
(forward_propagate_into_cond): Likewise.

* gcc.dg/tree-ssa/forwprop-16.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178634 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 224e1a5..5cde3b1 100644 (file)
@@ -1,5 +1,11 @@
 2011-09-07  Richard Guenther  <rguenther@suse.de>
 
+       * tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
+       Canonicalize negated predicates by swapping edges.
+       (forward_propagate_into_cond): Likewise.
+
+2011-09-07  Richard Guenther  <rguenther@suse.de>
+
        PR tree-optimization/50213
        * tree-flow.h (simple_iv_increment_p): Declare.
        * tree-ssa-dom.c (simple_iv_increment_p): Export.  Also handle
index 04d41dc..82b748f 100644 (file)
@@ -1,3 +1,7 @@
+2011-09-07  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/forwprop-16.c: New testcase.
+
 2011-09-07  Jiangning Liu  <jiangning.liu@arm.com>
 
        PR tree-optimization/46021
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-16.c
new file mode 100644 (file)
index 0000000..b47edea
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+int foo (double xx, double xy)
+{
+  int p = xx < xy;
+  int np = !p; 
+  if (np)
+    return 5;
+  return 2;
+}
+
+/* { dg-final { scan-tree-dump "if \\\(x" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
index ae37095..6333ed6 100644 (file)
@@ -534,6 +534,23 @@ forward_propagate_into_gimple_cond (gimple stmt)
       return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
     }
 
+  /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges.  */
+  if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE
+       || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+          && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
+      && ((code == EQ_EXPR
+          && integer_zerop (rhs2))
+         || (code == NE_EXPR
+             && integer_onep (rhs2))))
+    {
+      basic_block bb = gimple_bb (stmt);
+      gimple_cond_set_code (stmt, NE_EXPR);
+      gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
+      EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
+      EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
+      return 1;
+    }
+
   return 0;
 }
 
@@ -548,6 +565,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
   gimple stmt = gsi_stmt (*gsi_p);
   tree tmp = NULL_TREE;
   tree cond = gimple_assign_rhs1 (stmt);
+  bool swap = false;
 
   /* We can do tree combining on SSA_NAME and comparison expressions.  */
   if (COMPARISON_CLASS_P (cond))
@@ -557,17 +575,27 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
                                               TREE_OPERAND (cond, 1));
   else if (TREE_CODE (cond) == SSA_NAME)
     {
+      enum tree_code code;
       tree name = cond;
       gimple def_stmt = get_prop_source_stmt (name, true, NULL);
       if (!def_stmt || !can_propagate_from (def_stmt))
        return 0;
 
-      if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
+      code = gimple_assign_rhs_code (def_stmt);
+      if (TREE_CODE_CLASS (code) == tcc_comparison)
        tmp = fold_build2_loc (gimple_location (def_stmt),
-                              gimple_assign_rhs_code (def_stmt),
+                              code,
                               boolean_type_node,
                               gimple_assign_rhs1 (def_stmt),
                               gimple_assign_rhs2 (def_stmt));
+      else if ((code == BIT_NOT_EXPR
+               && TYPE_PRECISION (TREE_TYPE (cond)) == 1)
+              || (code == BIT_XOR_EXPR
+                  && integer_onep (gimple_assign_rhs2 (def_stmt))))
+       {
+         tmp = gimple_assign_rhs1 (def_stmt);
+         swap = true;
+       }
     }
 
   if (tmp)
@@ -586,7 +614,15 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
       else if (integer_zerop (tmp))
        gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
       else
-       gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
+       {
+         gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
+         if (swap)
+           {
+             tree t = gimple_assign_rhs2 (stmt);
+             gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt));
+             gimple_assign_set_rhs3 (stmt, t);
+           }
+       }
       stmt = gsi_stmt (*gsi_p);
       update_stmt (stmt);