This moves the canonicalization of `bool==0` and `bool!=1` from
forwprop to cleanupcfg. We will still need to call it from forwprop
so we don't need to call forwprop a few times to fp comparisons in some
cases (forwprop-16.c was added originally for this code even).

This is the first step in removing forward_propagate_into_gimple_cond
and forward_propagate_into_comparison.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

        * tree-cfgcleanup.cc (canonicalize_bool_cond): New function.
        (cleanup_control_expr_graph): Call canonicalize_bool_cond for 
GIMPLE_COND.
        * tree-cfgcleanup.h (canonicalize_bool_cond): New declaration.
        * tree-ssa-forwprop.cc (forward_propagate_into_gimple_cond):
        Call canonicalize_bool_cond.

Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
 gcc/tree-cfgcleanup.cc   | 39 +++++++++++++++++++++++++++++++++++++++
 gcc/tree-cfgcleanup.h    |  1 +
 gcc/tree-ssa-forwprop.cc | 18 ++----------------
 3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 38a62499f93..66575393a44 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-into-ssa.h"
 #include "tree-cfgcleanup.h"
 #include "target.h"
+#include "gimple-pretty-print.h"
 
 
 /* The set of blocks in that at least one of the following changes happened:
@@ -123,6 +124,41 @@ convert_single_case_switch (gswitch *swtch, 
gimple_stmt_iterator &gsi)
   return true;
 }
 
+/* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 of STMT in BB by
+   swapping edges of the BB.  */
+bool
+canonicalize_bool_cond (gcond *stmt, basic_block bb)
+{
+  tree rhs1 = gimple_cond_lhs (stmt);
+  tree rhs2 = gimple_cond_rhs (stmt);
+  enum tree_code code = gimple_cond_code (stmt);
+  if (code != EQ_EXPR && code != NE_EXPR)
+    return false;
+  if (TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE
+      && (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+          || TYPE_PRECISION (TREE_TYPE (rhs1)) != 1))
+    return false;
+
+  /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges.  
*/
+  if (code == EQ_EXPR && !integer_zerop (rhs2))
+    return false;
+  if (code == NE_EXPR && !integer_onep (rhs2))
+    return false;
+
+  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);
+
+  if (dump_file)
+    {
+      fprintf (dump_file, "  Swapped '");
+      print_gimple_expr (dump_file, stmt, 0);
+      fprintf (dump_file, "'\n");
+    }
+  return true;
+}
+
 /* Disconnect an unreachable block in the control expression starting
    at block BB.  */
 
@@ -146,6 +182,9 @@ cleanup_control_expr_graph (basic_block bb, 
gimple_stmt_iterator gsi)
          && convert_single_case_switch (as_a<gswitch *> (stmt), gsi))
        stmt = gsi_stmt (gsi);
 
+      if (gimple_code (stmt) == GIMPLE_COND)
+       canonicalize_bool_cond (as_a<gcond*> (stmt), bb);
+
       fold_defer_overflow_warnings ();
       switch (gimple_code (stmt))
        {
diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h
index 83c857fe33a..94b430e0c71 100644
--- a/gcc/tree-cfgcleanup.h
+++ b/gcc/tree-cfgcleanup.h
@@ -28,5 +28,6 @@ extern bool delete_unreachable_blocks_update_callgraph 
(cgraph_node *dst_node,
                                                        bool update_clones);
 extern unsigned clean_up_loop_closed_phi (function *);
 extern bool phi_alternatives_equal (basic_block, edge, edge);
+extern bool canonicalize_bool_cond (gcond *stmt, basic_block bb);
 
 #endif /* GCC_TREE_CFGCLEANUP_H */
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index bd407ef8a69..d718d8f7faf 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -579,22 +579,8 @@ forward_propagate_into_gimple_cond (gcond *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;
-    }
+  if (canonicalize_bool_cond (stmt, gimple_bb (stmt)))
+    return 1;
 
   return 0;
 }
-- 
2.43.0

Reply via email to