On Fri, Nov 13, 2026 at 12:01 PM Matt Turner <[email protected]> wrote: > > When a peephole2 replaces a call, the REG_EH_REGION note is copied by > copy_reg_eh_region_note_backward, which skips insns that can't throw. > Without -fexceptions that includes the new call, so a nothrow note > (lp_nr INT_MIN) is lost. In a function with nonlocal labels the call > is then treated as a possible nonlocal goto and ends a basic block, > which rtl_verify_bb_insns rejects: > > error: flow control insn inside a basic block > internal compiler error: in rtl_verify_bb_insns, at cfgrtl.cc:3011 > > Seen on alpha-linux with gcc.dg/asan/pr81186.c and pr82545.c at -O2.
So maybe then copy_reg_eh_region_note_backward should instead. That is copy the nothrow EH_REGION reg note to all calls instead of just the throwing regions. Likewise for copy_reg_eh_region_note_forward . So copy 0 and INT_MIN to all calls in copy_reg_eh_region_note_backward and copy_reg_eh_region_note_forward. Thanks, Andrea > > gcc/ChangeLog: > > * recog.cc (peep2_attempt): Copy REG_EH_REGION notes to a new > call that can't throw. > --- > gcc/recog.cc | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/gcc/recog.cc b/gcc/recog.cc > index 188ebc37834..848f473c3be 100644 > --- a/gcc/recog.cc > +++ b/gcc/recog.cc > @@ -4140,6 +4140,12 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int > match_len, rtx_insn *attempt) > add_reg_note (new_insn, REG_NOTE_KIND (note), > XEXP (note, 0)); > break; > + case REG_EH_REGION: > + /* copy_reg_eh_region_note_backward below only handles insns > + that could throw. */ > + if (!insn_could_throw_p (new_insn)) > + add_reg_note (new_insn, REG_EH_REGION, XEXP (note, 0)); > + break; > default: > /* Discard all other reg notes. */ > break; > > -- > 2.56.1 >
