diff mbox

[RS6000] Fix PR54093, ICE due to 07-24 changes

Message ID 20120727132654.GO3182@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra July 27, 2012, 1:26 p.m. UTC
This fixes a thinko and typo in
http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01168.html that shows up
as an ICE on e500.  Two issues really.  One is that the secondary
reload insn emitted by rs6000_secondary_reload_gpr had better be
valid.  The other is that we only need these reloads when the
insn predicate says that the address is good.  Fixing the second
problem avoids the first.

Bootstrapped and regression tested powerpc-linux, and fixes the
testcases in the PR on e500.  OK to apply?

	* config/rs6000/rs6000.c (rs6000_secondary_reload): Limit 32-bit
	multi-gpr reload to cases where predicate passes.  Do the same for
	64-bit multi-gpr reload.

Comments

David Edelsohn July 27, 2012, 2:46 p.m. UTC | #1
On Fri, Jul 27, 2012 at 9:26 AM, Alan Modra <amodra@gmail.com> wrote:
> This fixes a thinko and typo in
> http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01168.html that shows up
> as an ICE on e500.  Two issues really.  One is that the secondary
> reload insn emitted by rs6000_secondary_reload_gpr had better be
> valid.  The other is that we only need these reloads when the
> insn predicate says that the address is good.  Fixing the second
> problem avoids the first.
>
> Bootstrapped and regression tested powerpc-linux, and fixes the
> testcases in the PR on e500.  OK to apply?
>
>         * config/rs6000/rs6000.c (rs6000_secondary_reload): Limit 32-bit
>         multi-gpr reload to cases where predicate passes.  Do the same for
>         64-bit multi-gpr reload.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 189801)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -13643,8 +13643,11 @@  rs6000_secondary_reload (bool in_p,
 	   && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
     {
       rtx off = address_offset (XEXP (x, 0));
+      unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD;
 
-      if (off != NULL_RTX && (INTVAL (off) & 3) != 0)
+      if (off != NULL_RTX
+	  && (INTVAL (off) & 3) != 0
+	  && (unsigned HOST_WIDE_INT) INTVAL (off) + 0x8000 < 0x10000 - extra)
 	{
 	  if (in_p)
 	    sri->icode = CODE_FOR_reload_di_load;
@@ -13662,10 +13665,17 @@  rs6000_secondary_reload (bool in_p,
 	   && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
     {
       rtx off = address_offset (XEXP (x, 0));
+      unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD;
 
+      /* We need a secondary reload only when our legitimate_address_p
+	 says the address is good (as otherwise the entire address
+	 will be reloaded).  So for mode sizes of 8 and 16 this will
+	 be when the offset is in the ranges [0x7ffc,0x7fff] and
+	 [0x7ff4,0x7ff7] respectively.  Note that the address we see
+	 here may have been manipulated by legitimize_reload_address.  */
       if (off != NULL_RTX
-	  && ((unsigned HOST_WIDE_INT) INTVAL (off) + 0x8000
-	      >= 0x1000u - (GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD)))
+	  && ((unsigned HOST_WIDE_INT) INTVAL (off) - (0x8000 - extra)
+	      < UNITS_PER_WORD))
 	{
 	  if (in_p)
 	    sri->icode = CODE_FOR_reload_si_load;