On Wed, May 13, 2026 at 8:51 AM Andrew Pinski <[email protected]> wrote: > > On Tue, May 12, 2026 at 11:38 PM Richard Biener > <[email protected]> wrote: > > > > On Wed, May 13, 2026 at 1:46 AM Andrew Pinski > > <[email protected]> wrote: > > > > > > So the problem here is that group_case_labels_stmt can remove all > > > cases if they all go directly to a BB just containing > > > __builtin_unreachable. So we left with a switch which has one label > > > left; the default case. Code in ifcvt (which is the pass right after > > > this cleanup happens) is not ready for that case because well it is just > > > an fallthrough at this point and it should not have to worry about it. > > > > > > I have not figured out why this only started to show up recently but > > > it is definitely a latent bug since group_case_labels_stmt started > > > removing > > > case labels that go to a BB that contains __builtin_unreachable; > > > r8-546-gca4d2851687875. > > > > Huh, I didn't expect end_recording_case_labels to affect the CFG. Which > > is why I'm also worried about this patch ... > > > > IMO this belongs to CFG cleanup. I see we're recording case labels > > only from two places, critical edge splitting, CFG cleanup itself and > > uninit analysis. Only CFG cleanup should have exposed the need > > for r8-546, right? So ... can we somehow move this all there? > > Yes I agree it belongs in a different place from the current > placement. In fact I think it should not happen until after vrp1. > I will look into moving it tomorrow as the first step. Though since > this is a regression so the big question is what do we do for GCC 16 > branch?
What happens if we revert r8-546? > > Thanks, > Andrew > > > > > > What this does is if group_case_labels_stmt returns true and we only > > > have a default case left; remove the switch and change the flow into > > > a fallthrough. > > > > > > There is some slight cleanups in end_recording_case_labels done > > > with just using continue instead f indention to make it easier > > > to read on what is going on. > > > > > > Bootstrapped and tested on x86_64-linux-gnu. > > > > > > PR tree-optimization/125290 > > > > > > gcc/ChangeLog: > > > > > > * tree-cfg.cc (end_recording_case_labels): Fixup > > > case for only switch with default case left. > > > > > > gcc/testsuite/ChangeLog: > > > > > > * gcc.dg/torture/pr125290-1.c: New test. > > > > > > Signed-off-by: Andrew Pinski <[email protected]> > > > --- > > > gcc/testsuite/gcc.dg/torture/pr125290-1.c | 40 +++++++++++++++++++++++ > > > gcc/tree-cfg.cc | 20 +++++++++--- > > > 2 files changed, 56 insertions(+), 4 deletions(-) > > > create mode 100644 gcc/testsuite/gcc.dg/torture/pr125290-1.c > > > > > > 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 00000000000..6183cbd2681 > > > --- /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 b2968c412ed..da6d6b34da8 100644 > > > --- a/gcc/tree-cfg.cc > > > +++ b/gcc/tree-cfg.cc > > > @@ -1271,10 +1271,22 @@ end_recording_case_labels (void) > > > EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi) > > > { > > > basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); > > > - if (bb) > > > - { > > > - if (gswitch *stmt = safe_dyn_cast <gswitch *> (*gsi_last_bb > > > (bb))) > > > - group_case_labels_stmt (stmt); > > > + if (!bb) > > > + continue; > > > + gswitch *stmt = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)); > > > + if (!stmt) > > > + continue; > > > + if (group_case_labels_stmt (stmt) > > > + && gimple_switch_num_labels (stmt) == 1) > > > + { > > > + /* group_case_labels_stmt can remove all > > > + cases except for the default (via __builtin_unreachable()) > > > + so fixup that case. */ > > > + edge taken_edge = single_succ_edge (bb); > > > + auto gsi = gsi_last_bb (bb); > > > + gsi_remove (&gsi, true); > > > + taken_edge->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); > > > + taken_edge->flags |= EDGE_FALLTHRU; > > > } > > > } > > > BITMAP_FREE (touched_switch_bbs); > > > -- > > > 2.43.0 > > >
