]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/54131 (ICE building 416.gamess, reload_cse_simplify_operands)
authorAlan Modra <amodra@gmail.com>
Tue, 31 Jul 2012 22:14:44 +0000 (07:44 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Tue, 31 Jul 2012 22:14:44 +0000 (07:44 +0930)
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.

From-SVN: r190022

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index a137c7fa2621d09af1075b410a3c341623938ce4..1947fdff5cd25e5bb17aa33c4caa078faaf46fc4 100644 (file)
@@ -1,3 +1,10 @@
+2012-08-01  Alan Modra  <amodra@gmail.com>
+
+       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.
+
 2012-07-31  Bill Schmidt  <wschmidt@linux.ibm.com>
 
        * config/rs6000/rs6000.c (rs6000_builtin_vectorization_cost): Revise
index b68082c143fd7cfd6cfbdc47c2315bda6937ecf2..34948fb21c72c4cb5f87764944a7eb4c96d35dd4 100644 (file)
@@ -5070,24 +5070,38 @@ address_offset (rtx op)
 
    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);
-  extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
-  if (extra < 0)
-    extra = 0;
-  else if (TARGET_POWERPC64 && (offset & 3) != 0)
+  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;
+  gcc_assert (extra >= 0);
   return offset + 0x8000 < 0x10000u - extra;
 }
 \f