Patchwork Fix ACATS c94007a on 4.6 branch for SPARC64/Solaris

login
register
mail settings
Submitter Eric Botcazou
Date June 21, 2011, 8:54 p.m.
Message ID <201106212254.49936.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/101365/
State New
Headers show

Comments

Eric Botcazou - June 21, 2011, 8:54 p.m.
This is the failure of ACATS c94007a at -O2 on SPARC64/Solaris: the compiler
generates wrong code because of a delay slot scheduling (reorg.c) bug.  This
is a regression on the 4.6 branch (4.5 branch and mainline are clean).

fill_simple_delay_slots decides to fill the delay slot of a call insn with
another insn that is located about one hundred insns downstream(!); this is
a long sequence of call insns that can throw with handlers that fall thru,
a typical pattern of ACATS tests, without any intervening jumps or labels.

The problem is that fill_simple_delay_slots hoists the insn above such a
call that throws and whose handler falls thru, which makes it effectively a
jump with edges in the CFG.  The code handles the regular jump case:

  /* Stop our search when seeing an unconditional jump.  */
  if (JUMP_P (trial_delay))
    break;

but overlooks this special jump case.  This is a known pattern, whose solution
has been factored into stop_search_p:

/* Return TRUE if this insn should stop the search for insn to fill delay
   slots.  LABELS_P indicates that labels should terminate the search.
   In all cases, jumps terminate the search.  */

static int
stop_search_p (rtx insn, int labels_p)
{
  if (insn == 0)
    return 1;

  /* If the insn can throw an exception that is caught within the function,
     it may effectively perform a jump from the viewpoint of the function.
     Therefore act like for a jump.  */
  if (can_throw_internal (insn))
    return 1;


fill_simple_delay_slots already uses stop_search_p for the backward scan.
The fix is simply to make it use stop_search_p for the forward scan as well.

Bootstrappeg/regtested on SPARC/Solaris and SPARC64/Solaris.


2011-06-21  Eric Botcazou  <ebotcazou@adacore.com>

	* reorg.c (fill_simple_delay_slots): Use stop_search_p to stop the
	forward scan as well.
Eric Botcazou - June 27, 2011, 1 p.m.
> 2011-06-21  Eric Botcazou  <ebotcazou@adacore.com>
>
> 	* reorg.c (fill_simple_delay_slots): Use stop_search_p to stop the
> 	forward scan as well.

Applied on the mainline and 4.6 branch after re-bootstrapping on SPARC/Solaris.

Patch

Index: reorg.c
===================================================================
--- reorg.c	(revision 175090)
+++ reorg.c	(working copy)
@@ -2152,7 +2152,7 @@  fill_simple_delay_slots (int non_jumps_p
 	      /* This must be an INSN or CALL_INSN.  */
 	      pat = PATTERN (trial);
 
-	      /* USE and CLOBBER at this level was just for flow; ignore it.  */
+	      /* Stand-alone USE and CLOBBER are just for flow.  */
 	      if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
 		continue;
 
@@ -2271,15 +2271,12 @@  fill_simple_delay_slots (int non_jumps_p
 	    }
 
 	  if (target == 0)
-	    for (trial = next_nonnote_insn (insn); trial; trial = next_trial)
+	    for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1);
+		 trial = next_trial)
 	      {
 		next_trial = next_nonnote_insn (trial);
 
-		if (LABEL_P (trial)
-		    || BARRIER_P (trial))
-		  break;
-
-		/* We must have an INSN, JUMP_INSN, or CALL_INSN.  */
+		/* This must be an INSN or CALL_INSN.  */
 		pat = PATTERN (trial);
 
 		/* Stand-alone USE and CLOBBER are just for flow.  */
@@ -2293,7 +2290,7 @@  fill_simple_delay_slots (int non_jumps_p
 		else
 		  trial_delay = trial;
 
-		/* Stop our search when seeing an unconditional jump.  */
+		/* Stop our search when seeing a jump.  */
 		if (JUMP_P (trial_delay))
 		  break;