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.
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