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
>

Reply via email to