From patchwork Tue Jul 31 11:51:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [RS6000] Fix PR54131, ICE building 416.gamess Date: Tue, 31 Jul 2012 01:51:21 -0000 From: Alan Modra X-Patchwork-Id: 174254 Message-Id: <20120731115121.GS3182@bubble.grove.modra.org> To: David Edelsohn , Pat Haugen Cc: gcc-patches@gcc.gnu.org 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. 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; }