https://gcc.gnu.org/g:c6781f5558bdb4f241a3597c528ed7020a5cfce7

commit r16-4014-gc6781f5558bdb4f241a3597c528ed7020a5cfce7
Author: Andrew Pinski <[email protected]>
Date:   Fri Sep 19 12:23:57 2025 -0700

    fab: Remove forced label check from optimize_unreachable
    
    Since optimize_unreachable does not directly remove the bb, we can still 
remove
    the condition that goes to a block containing a forced label. This is a 
small cleanup
    from the original patch which added optimize_unreachable.
    
    The review of the original patch missed that the bb was not being removed 
by the pass
    but later on by cleanupcfg; 
https://gcc.gnu.org/pipermail/gcc-patches/2012-July/343239.html.
    Which is why this is allowed to be done.
    
    I added another testcase to check that the `if` is removed too.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
    gcc/ChangeLog:
    
            * tree-ssa-ccp.cc (optimize_unreachable): Don't check for forced 
labels.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/builtin-unreachable-7.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/builtin-unreachable-7.c | 24 +++++++++++++++++++++++
 gcc/tree-ssa-ccp.cc                          | 29 ++++++----------------------
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/builtin-unreachable-7.c 
b/gcc/testsuite/gcc.dg/builtin-unreachable-7.c
new file mode 100644
index 000000000000..a6c078fef285
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-unreachable-7.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fab1 -fno-tree-dominator-opts -fno-tree-vrp" 
} */
+/* { dg-require-effective-target label_values } */
+
+void foo (int b, int c)
+{
+  __label__ lab;
+  __label__ lab2;
+  static void *x[2] = {&&lab, &&lab2};
+  if (b == c)
+    {
+lab:
+      __builtin_unreachable ();
+    }
+lab2:
+  goto *x[c!=0];
+}
+
+/* Fab should still able to remove the conditional but leave the bb there. */
+
+/* { dg-final { scan-tree-dump-times "lab:" 1 "fab1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_unreachable" 1 "fab1" } } */
+/* { dg-final { scan-tree-dump-not "if " "fab1" } } */
+
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index f16b37f193e2..546cafbf7c69 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -3260,29 +3260,12 @@ optimize_unreachable (gimple_stmt_iterator i)
 
   if (flag_sanitize & SANITIZE_UNREACHABLE)
     return false;
-
-  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    {
-      stmt = gsi_stmt (gsi);
-
-      if (is_gimple_debug (stmt))
-       continue;
-
-      if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
-       {
-         /* Verify we do not need to preserve the label.  */
-         if (FORCED_LABEL (gimple_label_label (label_stmt)))
-           return false;
-
-         continue;
-       }
-
-      /* 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_stmt (gsi) != gsi_stmt (i))
-        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)

Reply via email to