https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121843
--- Comment #3 from Jeevitha <jeevitha at gcc dot gnu.org> ---
last is NULL because prev_nonnote_insn(before) finds no real instruction before
the jump in BB6(during NOTE_INSN_PROLOGUE_END insertion). Both checks are
inapplicable when last is NULL — returnjump_p only applies for epilogue
insertion before a return jump, and gcc_assert(!JUMP_P(last)) only guards
against a preceding jump bypassing inserted insns.
BB6 is created by split_edge when commit_one_edge_insertion processes the
BB4→BB2 edge to insert the r23 epilogue restore during shrink-wrapping. Since
BB2 has multiple predecessors, split_edge is called which creates BB6
containing only an unconditional jump to BB2 with no preceding real insns. When
the prologue note is later inserted at the start of BB6, prev_nonnote_insn
returns NULL causing the crash.
Is the NULL guard the correct fix here? The prologue insertion into BB6 does
not involve a return jump, and the CFG structure created by split_edge appears
valid.
if (last != NULL)
{
if (returnjump_p (last))
{
/* ??? Remove all outgoing edges from BB and add one for EXIT.
This is not currently a problem because this only happens
for the (single) epilogue, which already has a fallthru edge
to EXIT. */
e = single_succ_edge (bb);
gcc_assert (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)
&& single_succ_p (bb) && (e->flags & EDGE_FALLTHRU));
e->flags &= ~EDGE_FALLTHRU;
emit_barrier_after (last);
if (before)
delete_insn (before);
}
else
/* Sequences inserted after RTL expansion are expected to be SESE,
with only internal branches allowed. If the sequence jumps outside
itself then we do not know how to add the associated edges here. */
gcc_assert (!JUMP_P (last) || currently_expanding_to_rtl);
}