]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gimple: Move canonicalization of bool==0 and bool!=1 to cleanupcfg
authorAndrew Pinski <quic_apinski@quicinc.com>
Tue, 13 May 2025 21:27:12 +0000 (14:27 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Wed, 14 May 2025 14:56:23 +0000 (07:56 -0700)
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_apinski@quicinc.com>
gcc/tree-cfgcleanup.cc
gcc/tree-cfgcleanup.h
gcc/tree-ssa-forwprop.cc

index 9a8a668e12b864b9a9f7e9ccf1d79683aa883c4c..a34a51ec18619d6421d6adf806033a7515bccc70 100644 (file)
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-into-ssa.h"
 #include "tree-cfgcleanup.h"
+#include "gimple-pretty-print.h"
 
 
 /* The set of blocks in that at least one of the following changes happened:
@@ -122,6 +123,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.  */
 
@@ -145,6 +181,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))
        {
index 83c857fe33a0b8c243c3c5b6891372b65f36352c..94b430e0c7130c5b3e80ec7983d38c599d90b24f 100644 (file)
@@ -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 */
index 60b7c80e07c29507ffd2a255e17dba3198ab5009..3187314390f617de13c8948156794c8630495bbf 100644 (file)
@@ -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;
 }