diff mbox series

[Committed] patch fixing LRA crash on s390x

Message ID 0b062f7d-4a76-ed49-6959-bb33dbb13823@redhat.com
State New
Headers show
Series [Committed] patch fixing LRA crash on s390x | expand

Commit Message

Vladimir Makarov Nov. 15, 2020, 5:08 p.m. UTC
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 <vmakarov@redhat.com>
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.

Comments

Jakub Jelinek Nov. 22, 2020, 10:23 a.m. UTC | #1
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
diff mbox series

Patch

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 ();