diff mbox

[RS6000] pr57936, ICE in rs6000_secondary_reload_inner

Message ID 20140226075412.GA14922@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Feb. 26, 2014, 7:54 a.m. UTC
On Wed, Feb 26, 2014 at 01:03:52AM +1030, Alan Modra wrote:
> On Tue, Feb 25, 2014 at 02:30:59PM +0100, Ulrich Weigand wrote:
> > Instead, there's code in emit_input_reload_insns that is supposed
> > to re-check whether a secondary reload is still needed if something
> > changed significantly, e.g. if a value was inherited:

> reload_override_in[j] is (reg:V16QI 32 0), and rl->in_reg is
> (subreg:V16QI (reg:V2DI 159 [ D.2446 ]) 0), so perhaps we're missing a
> subreg test in
> 
>   if (reload_override_in[j]
>       && REG_P (rl->in_reg))
>     {
>       oldequiv = old;
>       old = rl->in_reg;
>     }

Yes, that was it.  I did wonder why the secondary reload wasn't being
deleted but didn't spot the code in emit_input_reload_insns..

Some notes:  Setting old to rl->in_reg when it is a subreg doesn't
change the cases where delete_output_reload is called, since that call
is protected by REG_P (old).  The same thing goes for the following:

  /* If we are reloading a pseudo-register that was set by the previous
     insn, see if we can get rid of that pseudo-register entirely
     by redirecting the previous insn into our reload register.  */

  else if (optimize && REG_P (old)

Perhaps the above could handle subregs too, but I figure such a change
probably isn't good for stage 4.  So the net result of this patch
ought to just change the conditions under which we recheck secondary
reloads.

Bootstrapped and regression tested powerpc64-linux, x86_64-linux
bootstrap still chugging along.  OK to apply, assuming no regressions?

	PR target/57935
	* reload1.c (emit_input_reload_insns): When reload_override_in,
	set old to rl->in_reg when rl->in_reg is a subreg.
diff mbox

Patch

Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	(revision 208097)
+++ gcc/reload1.c	(working copy)
@@ -7238,9 +7238,12 @@  emit_input_reload_insns (struct insn_chain *chain,
   /* delete_output_reload is only invoked properly if old contains
      the original pseudo register.  Since this is replaced with a
      hard reg when RELOAD_OVERRIDE_IN is set, see if we can
-     find the pseudo in RELOAD_IN_REG.  */
+     find the pseudo in RELOAD_IN_REG.  This is also used to
+     determine whether a secondary reload is needed.  */
   if (reload_override_in[j]
-      && REG_P (rl->in_reg))
+      && (REG_P (rl->in_reg)
+	  || (GET_CODE (rl->in_reg) == SUBREG
+	      && REG_P (SUBREG_REG (rl->in_reg)))))
     {
       oldequiv = old;
       old = rl->in_reg;