Re: [Committed] patch fixing LRA crash on s390x
On Sun, Nov 15, 2020 at 12:08:22PM -0500, Vladimir Makarov via Gcc-patches wrote: > --- a/gcc/lra.c > +++ b/gcc/lra.c > @@ -1903,15 +1903,23 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn > *before, rtx_insn *after, > { > /* We already made the edge no-critical in ira.c::ira */ > lra_assert (!EDGE_CRITICAL_P (e)); > - rtx_insn *tmp = BB_HEAD (e->dest); > + rtx_insn *curr, *tmp = BB_HEAD (e->dest); > if (LABEL_P (tmp)) > tmp = NEXT_INSN (tmp); > if (NOTE_INSN_BASIC_BLOCK_P (tmp)) > tmp = NEXT_INSN (tmp); > - start_sequence (); > - for (rtx_insn *curr = after; > - curr != NULL_RTX; > + for (curr = tmp; > + curr != NULL > +&& (!INSN_P (curr) || BLOCK_FOR_INSN (curr) == e->dest); >curr = NEXT_INSN (curr)) > + ; > + /* Do not put reload insns if it is the last BB > +without actual insns. In this case the reload insns > +can get null BB after emitting. */ What the above loop does doesn't match what the comment says. Because the loop will result in curr == NULL even if e->dest contains any number of actual insns, only cares about whether e->dest's next_bb has no actual insns or there is no next bb at all. Did you mean something like for (curr = tmp; curr != NULL; curr = NEXT_INSN (curr)) if (INSN_P (curr)) break; (i.e. it would be non-NULL if the e->dest bb contains any actual insns, or if it isn't the last bb and there is at least one further bb with actual insns after it)? See PR97933 for details. Jakub
[Committed] patch fixing LRA crash on s390x
My last patch implementing output reloads in asm goto resulted in LRA crash in compiling kernel on s390x. Jeff Law reported it recently. The culprit was in incorrect emitting reload insns in last empty BB. The emitted insns got null BB which is wrong. Actually in this case we do not need to emit such insns as they will removed as dead lately. The following patch fixes the problem. Author: Vladimir N. Makarov Date: Sun Nov 15 11:22:19 2020 -0500 Do not put reload insns in the last empty BB. gcc/ * lra.c (lra_process_new_insns): Don't put reload insns in the last empty BB. diff --git a/gcc/lra.c b/gcc/lra.c index 673554d0a4b..b318cfd7456 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -1903,15 +1903,23 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, { /* We already made the edge no-critical in ira.c::ira */ lra_assert (!EDGE_CRITICAL_P (e)); - rtx_insn *tmp = BB_HEAD (e->dest); + rtx_insn *curr, *tmp = BB_HEAD (e->dest); if (LABEL_P (tmp)) tmp = NEXT_INSN (tmp); if (NOTE_INSN_BASIC_BLOCK_P (tmp)) tmp = NEXT_INSN (tmp); - start_sequence (); - for (rtx_insn *curr = after; -curr != NULL_RTX; + for (curr = tmp; +curr != NULL + && (!INSN_P (curr) || BLOCK_FOR_INSN (curr) == e->dest); curr = NEXT_INSN (curr)) + ; + /* Do not put reload insns if it is the last BB + without actual insns. In this case the reload insns + can get null BB after emitting. */ + if (curr == NULL) + continue; + start_sequence (); + for (curr = after; curr != NULL_RTX; curr = NEXT_INSN (curr)) emit_insn (copy_insn (PATTERN (curr))); rtx_insn *copy = get_insns (), *last = get_last_insn (); end_sequence ();