diff mbox

[RS6000] Fix PR54131, ICE building 416.gamess

Message ID 20120731115121.GS3182@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra July 31, 2012, 11:51 a.m. UTC
This cures the 'Y' constraint of being overly restrictive with lo_sum
offsets.  I've added a comment that explains why it is wrong to limit
the range of lo_sum offsets.  Bootstrapped and regressiotn tested
powerpc-linux.  OK to apply?

	PR target/54131
	* config/rs6000/rs6000.c (mem_operand_gpr): Don't limit range
	of lo_sum offsets.  Comment.  Assert mode at least word size
	rather than bypassing powerpc64 word offset check.

Comments

David Edelsohn July 31, 2012, 2:31 p.m. UTC | #1
On Tue, Jul 31, 2012 at 7:51 AM, Alan Modra <amodra@gmail.com> wrote:
> This cures the 'Y' constraint of being overly restrictive with lo_sum
> offsets.  I've added a comment that explains why it is wrong to limit
> the range of lo_sum offsets.  Bootstrapped and regressiotn tested
> powerpc-linux.  OK to apply?
>
>         PR target/54131
>         * config/rs6000/rs6000.c (mem_operand_gpr): Don't limit range
>         of lo_sum offsets.  Comment.  Assert mode at least word size
>         rather than bypassing powerpc64 word offset check.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 189996)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -5008,24 +5008,38 @@ 
 
    Offsetting a lo_sum should not be allowed, except where we know by
    alignment that a 32k boundary is not crossed, but see the ???
-   comment in rs6000_legitimize_reload_address.  */
+   comment in rs6000_legitimize_reload_address.  Note that by
+   "offsetting" here we mean a further offset to access parts of the
+   MEM.  It's fine to have a lo_sum where the inner address is offset
+   from a sym, since the same sym+offset will appear in the high part
+   of the address calculation.  */
 
 bool
 mem_operand_gpr (rtx op, enum machine_mode mode)
 {
   unsigned HOST_WIDE_INT offset;
   int extra;
+  rtx addr = XEXP (op, 0);
 
-  op = address_offset (XEXP (op, 0));
+  op = address_offset (addr);
   if (op == NULL_RTX)
     return true;
 
   offset = INTVAL (op);
+  if (TARGET_POWERPC64 && (offset & 3) != 0)
+    return false;
+
+  if (GET_CODE (addr) == LO_SUM)
+    /* We know by alignment that ABI_AIX medium/large model toc refs
+       will not cross a 32k boundary, since all entries in the
+       constant pool are naturally aligned and we check alignment for
+       other medium model toc-relative addresses.  For ABI_V4 and
+       ABI_DARWIN lo_sum addresses, we just check that 64-bit
+       offsets are 4-byte aligned.  */
+    return true;
+
   extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
-  if (extra < 0)
-    extra = 0;
-  else if (TARGET_POWERPC64 && (offset & 3) != 0)
-    return false;
+  gcc_assert (extra >= 0);
   return offset + 0x8000 < 0x10000u - extra;
 }