https://gcc.gnu.org/g:1dc8df6def07a924bdbb9741f8de30fbd7f3326a

commit r16-6153-g1dc8df6def07a924bdbb9741f8de30fbd7f3326a
Author: Andrew Pinski <[email protected]>
Date:   Sat Dec 13 16:23:33 2025 -0800

    cleanupcfg: Reject forwarder blocks where dest is eh landing pad or a 
non-local dest [PR123110]
    
    r16-5250-g88db06d7da393f901 changed which block was doing the
    check on the label being a non-local dest or an eh landing pad.
    Which is fine except then when we move labels we moved them to
    before the label for the non-local dest/eh landing pad.
    This can be fixed a few different ways.
    Add back the check for the dest block or change where the other
    labels are placed.
    Since this case does not happen enough to care either way, I added
    back the check for the dest block. This means there is no changes
    from GCC 15 to now.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/123110
    
    gcc/ChangeLog:
    
            * tree-cfgcleanup.cc (maybe_remove_forwarder_block): Add back
            check for eh landing pad or non-local dest on the dest.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/pr123110-1.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/pr123110-1.c | 31 +++++++++++++++++++++++++++++++
 gcc/tree-cfgcleanup.cc            |  7 +++++++
 2 files changed, 38 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/pr123110-1.c 
b/gcc/testsuite/gcc.dg/pr123110-1.c
new file mode 100644
index 000000000000..7feab6755457
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr123110-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fexceptions -finstrument-functions-once" } */
+/* PR tree-optimization/123110 */
+
+/* Make sure forwarder blocks (with labels) to eh landing pads are handled
+   correctly. */
+
+void baz ();
+
+int g, h;
+
+static inline __attribute__((__always_inline__)) void
+bar (int *out_base)
+{
+  if (!g)
+    {
+      baz ();
+      switch (h)
+       ;
+      return;
+    }
+fail:
+  *out_base = 0;
+}
+
+void
+foo ()
+{
+  unsigned base;
+  bar (&base);
+}
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 8060e90be79e..35b9985812d1 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -519,6 +519,13 @@ maybe_remove_forwarder_block (basic_block bb, bool 
can_split = false)
   bool has_phi = !gimple_seq_empty_p (phi_nodes (bb));
   basic_block dest = single_succ_edge (bb)->dest;
 
+  /* If the destination block consists of a nonlocal label or is a
+     EH landing pad, do not merge it.  */
+  if (glabel *label_stmt = safe_dyn_cast <glabel *> (first_stmt (dest)))
+    if (DECL_NONLOCAL (gimple_label_label (label_stmt))
+       || EH_LANDING_PAD_NR (gimple_label_label (label_stmt)))
+    return false;
+
   /* If there is an abnormal edge to basic block BB, but not into
      dest, problems might occur during removal of the phi node at out
      of ssa due to overlapping live ranges of registers.

Reply via email to