[gcc r16-9411] tree-cfg: Revert part of r8-546 [PR125290]

Andrea Pinski via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:8a8b309e0ec8447ad08e3d1c99b3b37e18272f02

commit r16-9411-g8a8b309e0ec8447ad08e3d1c99b3b37e18272f02
Author: Andrew Pinski <[email protected]>
Date:   Wed May 13 21:24:43 2026 -0700

    tree-cfg: Revert part of r8-546 [PR125290]
    
    This reverts the group_case_labels_stmt part of r8-546-gca4d2851687875.
    This is placed in the wrong location to remove the case statements that go
    directly to __builtin_unreachable. In fact the removal of the case statements
    make us lose optimizations in some cases (Wuninitialized-pr107919-1.C for one).
    
    Also this fixes PR 125290 by no longer leaving around a switch which just
    has a default case.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/125290
    
    gcc/ChangeLog:
    
            * tree-cfg.cc (group_case_labels_stmt): Remove code that was
            added to remove `cases` that goto blocks of unreachable.
            * tree-ssa-forwprop.cc (optimize_unreachable): Remove the
            comment about switch cases being handled.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/warn/Wuninitialized-pr107919-1.C: Remove xfail.
            * gcc.dg/analyzer/taint-assert.c: Update for the non-removal
            of block containing unreachable.
            * gcc.dg/torture/pr125290-1.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>
    (cherry picked from commit f108e23d2bff50d0ee8cf0d25a08be5432b702b6)

Diff:
---
 .../g++.dg/warn/Wuninitialized-pr107919-1.C        |  2 +-
 gcc/testsuite/gcc.dg/analyzer/taint-assert.c       |  4 +-
 gcc/testsuite/gcc.dg/torture/pr125290-1.c          | 40 +++++++++++++++++
 gcc/tree-cfg.cc                                    | 51 +---------------------
 gcc/tree-ssa-forwprop.cc                           |  3 +-
 5 files changed, 46 insertions(+), 54 deletions(-)

diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
index 049fa4d307ae..b3ed4628bdda 100644
--- a/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
@@ -14,4 +14,4 @@ void do_something(void* storage)
   std::swap(event, swappedValue);
 }
 
-// { dg-bogus "may be used uninitialized" "" { xfail *-*-* } 0 }
+// { dg-bogus "may be used uninitialized" "" 0 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-assert.c b/gcc/testsuite/gcc.dg/analyzer/taint-assert.c
index a858e996a801..e46cbe95801d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/taint-assert.c
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-assert.c
@@ -322,8 +322,8 @@ test_switch_bogus_case_unreachable (int n)
     case 2:
       return -1;
     case 42:
-      /* This case gets optimized away before we see it.  */
-      __builtin_unreachable ();
+      /* The wording is rather inaccurate here.  */
+      __builtin_unreachable (); /* { dg-warning "use of attacked-controlled value in condition for assertion" } */
     }
 }
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr125290-1.c b/gcc/testsuite/gcc.dg/torture/pr125290-1.c
new file mode 100644
index 000000000000..6183cbd26819
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125290-1.c
@@ -0,0 +1,40 @@
+/* PR tree-optimization/125290 */
+/* { dg-do compile } */
+
+int g21;
+int g31, f14f16_c12;
+void f14f16()
+{
+    short v7;
+    long v9;
+    long v13;
+    if (g31)
+    {
+        g21 = 0;
+        switch (v7)
+        {
+            case 4:
+            case 66: break;
+            default: __builtin_unreachable();
+        }
+    }
+    else
+    {
+    lbl_bf2:
+        v9 = g21;
+    }
+    v13 = v9;
+    switch (v13)
+    {
+        case 55:
+        case 2: goto lbl_sw12;
+        default:
+            if (f14f16_c12)
+                goto lbl_bf2;
+            else
+                return;
+    }
+lbl_sw12:
+    __builtin_unreachable();
+}
+
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index e42e22cf769f..51858d9f2655 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -1712,7 +1712,6 @@ group_case_labels_stmt (gswitch *stmt)
   int old_size = gimple_switch_num_labels (stmt);
   int i, next_index, new_size;
   basic_block default_bb = NULL;
-  hash_set<tree> *removed_labels = NULL;
 
   default_bb = gimple_switch_default_bb (cfun, stmt);
 
@@ -1728,12 +1727,9 @@ group_case_labels_stmt (gswitch *stmt)
       gcc_assert (base_case);
       base_bb = label_to_block (cfun, CASE_LABEL (base_case));
 
-      /* Discard cases that have the same destination as the default case or
-	 whose destination blocks have already been removed as unreachable.  */
+      /* Discard cases that have the same destination as the default case.  */
       if (base_bb == NULL
-	  || base_bb == default_bb
-	  || (removed_labels
-	      && removed_labels->contains (CASE_LABEL (base_case))))
+	  || base_bb == default_bb)
 	{
 	  i++;
 	  continue;
@@ -1756,8 +1752,6 @@ group_case_labels_stmt (gswitch *stmt)
 	  /* Merge the cases if they jump to the same place,
 	     and their ranges are consecutive.  */
 	  if (merge_bb == base_bb
-	      && (removed_labels == NULL
-		  || !removed_labels->contains (CASE_LABEL (merge_case)))
 	      && wi::to_wide (CASE_LOW (merge_case)) == bhp1)
 	    {
 	      base_high
@@ -1770,46 +1764,6 @@ group_case_labels_stmt (gswitch *stmt)
 	    break;
 	}
 
-      /* Discard cases that have an unreachable destination block.  */
-      if (EDGE_COUNT (base_bb->succs) == 0
-	  && gimple_seq_unreachable_p (bb_seq (base_bb))
-	  /* Don't optimize this if __builtin_unreachable () is the
-	     implicitly added one by the C++ FE too early, before
-	     -Wreturn-type can be diagnosed.  We'll optimize it later
-	     during switchconv pass or any other cfg cleanup.  */
-	  && (gimple_in_ssa_p (cfun)
-	      || (LOCATION_LOCUS (gimple_location (last_nondebug_stmt (base_bb)))
-		  != BUILTINS_LOCATION)))
-	{
-	  edge base_edge = find_edge (gimple_bb (stmt), base_bb);
-	  if (base_edge != NULL)
-	    {
-	      for (gimple_stmt_iterator gsi = gsi_start_bb (base_bb);
-		   !gsi_end_p (gsi); gsi_next (&gsi))
-		if (glabel *stmt = dyn_cast <glabel *> (gsi_stmt (gsi)))
-		  {
-		    if (FORCED_LABEL (gimple_label_label (stmt))
-			|| DECL_NONLOCAL (gimple_label_label (stmt)))
-		      {
-			/* Forced/non-local labels aren't going to be removed,
-			   but they will be moved to some neighbouring basic
-			   block. If some later case label refers to one of
-			   those labels, we should throw that case away rather
-			   than keeping it around and referring to some random
-			   other basic block without an edge to it.  */
-			if (removed_labels == NULL)
-			  removed_labels = new hash_set<tree>;
-			removed_labels->add (gimple_label_label (stmt));
-		      }
-		  }
-		else
-		  break;
-	      remove_edge_and_dominated_blocks (base_edge);
-	    }
-	  i = next_index;
-	  continue;
-	}
-
       if (new_size < i)
 	gimple_switch_set_label (stmt, new_size,
 				 gimple_switch_label (stmt, i));
@@ -1822,7 +1776,6 @@ group_case_labels_stmt (gswitch *stmt)
   if (new_size < old_size)
     gimple_switch_set_num_labels (stmt, new_size);
 
-  delete removed_labels;
   return new_size < old_size;
 }
 
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 6b745382fa0e..ce8bd0e0599d 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -5258,8 +5258,7 @@ optimize_unreachable (basic_block bb)
 	}
       else
 	{
-	  /* Todo: handle other cases.  Note that unreachable switch case
-	     statements have already been removed.  */
+	  /* Todo: handle other cases.  e.g. switch.  */
 	  continue;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.