]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fab/forwprop: Move optimize_unreachable to forwprop [PR121762]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Tue, 23 Sep 2025 19:14:47 +0000 (12:14 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 3 Oct 2025 14:29:07 +0000 (07:29 -0700)
This moves the optimize_unreachable to forwprop from fab.
There is a slightly optimization here in that the first
statement is checked and outside of the main fold loop. And if
the statement is __builtin_unreachable, then call optimize_unreachable.

Changes since v1:
* v2: simplified the check for BUILT_IN_UNREACHABLE to just use gimple_call_builtin_p.
      Move the code after checking for not executable blocks.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/121762
gcc/ChangeLog:

* tree-ssa-ccp.cc (optimize_unreachable): Move to tree-ssa-forwprop.cc
(pass_fold_builtins::execute): Remove handling of __builtin_unreachable.
* tree-ssa-forwprop.cc (optimize_unreachable): New function from
tree-ssa-ccp.cc. Change argument to bb. Remove check on first statement
being the __builtin_unreachable since it is handled already.
(pass_forwprop::execute): Handle first statement as being __builtin_unreachable
by calling optimize_unreachable.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/tree-ssa-ccp.cc
gcc/tree-ssa-forwprop.cc

index 739d3be9129334b040d22531033a0cba92baa823..b69a8b64a61bcc7c8c2b8b620c7dde428541e76a 100644 (file)
@@ -3202,58 +3202,6 @@ optimize_stdarg_builtin (gimple_stmt_iterator *gsi, gimple *call)
     }
 }
 
-/* Attemp to make the block of __builtin_unreachable I unreachable by changing
-   the incoming jumps.  Return true if at least one jump was changed.  */
-
-static bool
-optimize_unreachable (gimple_stmt_iterator i)
-{
-  basic_block bb = gsi_bb (i);
-  gimple_stmt_iterator gsi;
-  gimple *stmt;
-  edge_iterator ei;
-  edge e;
-  bool ret;
-
-  if (flag_sanitize & SANITIZE_UNREACHABLE)
-    return false;
-  gsi = gsi_start_nondebug_after_labels_bb (bb);
-  /* Only handle the case that __builtin_unreachable is the first
-     statement in the block.  We rely on DCE to remove stmts
-     without side-effects before __builtin_unreachable.  */
-  if (*gsi != *i)
-    return false;
-
-  ret = false;
-  FOR_EACH_EDGE (e, ei, bb->preds)
-    {
-      gsi = gsi_last_bb (e->src);
-      if (gsi_end_p (gsi))
-       continue;
-
-      stmt = gsi_stmt (gsi);
-      if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
-       {
-         if (e->flags & EDGE_TRUE_VALUE)
-           gimple_cond_make_false (cond_stmt);
-         else if (e->flags & EDGE_FALSE_VALUE)
-           gimple_cond_make_true (cond_stmt);
-         else
-           gcc_unreachable ();
-         update_stmt (cond_stmt);
-       }
-      else
-       {
-         /* Todo: handle other cases.  Note that unreachable switch case
-            statements have already been removed.  */
-         continue;
-       }
-
-      ret = true;
-    }
-
-  return ret;
-}
 
 /* Convert
    _1 = __atomic_fetch_or_* (ptr_6, 1, _3);
@@ -4235,12 +4183,6 @@ pass_fold_builtins::execute (function *fun)
              tree result = NULL_TREE;
              switch (DECL_FUNCTION_CODE (callee))
                {
-
-               case BUILT_IN_UNREACHABLE:
-                 if (optimize_unreachable (i))
-                   cfg_changed = true;
-                 break;
-
                case BUILT_IN_ATOMIC_ADD_FETCH_1:
                case BUILT_IN_ATOMIC_ADD_FETCH_2:
                case BUILT_IN_ATOMIC_ADD_FETCH_4:
index 941b01f3d0e24cf8d54264bb56705b3694ba46e0..9307e216207884696808c2a4187364a705026222 100644 (file)
@@ -4906,6 +4906,49 @@ public:
   bool m_full_walk = false;
 }; // class pass_forwprop
 
+/* Attemp to make the BB block of __builtin_unreachable unreachable by changing
+   the incoming jumps.  Return true if at least one jump was changed.  */
+
+static bool
+optimize_unreachable (basic_block bb)
+{
+  gimple_stmt_iterator gsi;
+  gimple *stmt;
+  edge_iterator ei;
+  edge e;
+  bool ret;
+
+  ret = false;
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    {
+      gsi = gsi_last_bb (e->src);
+      if (gsi_end_p (gsi))
+       continue;
+
+      stmt = gsi_stmt (gsi);
+      if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+       {
+         if (e->flags & EDGE_TRUE_VALUE)
+           gimple_cond_make_false (cond_stmt);
+         else if (e->flags & EDGE_FALSE_VALUE)
+           gimple_cond_make_true (cond_stmt);
+         else
+           gcc_unreachable ();
+         update_stmt (cond_stmt);
+       }
+      else
+       {
+         /* Todo: handle other cases.  Note that unreachable switch case
+            statements have already been removed.  */
+         continue;
+       }
+
+      ret = true;
+    }
+
+  return ret;
+}
+
 unsigned int
 pass_forwprop::execute (function *fun)
 {
@@ -4973,6 +5016,21 @@ pass_forwprop::execute (function *fun)
       if (!any)
        continue;
 
+      /* Remove conditions that go directly to unreachable when this is the last forwprop.  */
+      if (last_p
+         && !(flag_sanitize & SANITIZE_UNREACHABLE))
+       {
+         gimple_stmt_iterator gsi;
+         gsi = gsi_start_nondebug_after_labels_bb (bb);
+         if (!gsi_end_p (gsi)
+             && gimple_call_builtin_p (*gsi, BUILT_IN_UNREACHABLE)
+             && optimize_unreachable (bb))
+           {
+             cfg_changed = true;
+             continue;
+           }
+       }
+
       /* Record degenerate PHIs in the lattice.  */
       for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
           gsi_next (&si))