From patchwork Wed Feb 6 13:38:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 218608 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id CA6182C034E for ; Thu, 7 Feb 2013 00:39:03 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1360762744; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Date:From:To:Cc:Subject:Message-ID:Mail-Followup-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=sgb9OCvsjZUh/Gct55K8 eqhyahY=; b=Tcfe5ETxkcat1FvjP6tWemseQkj2J8pSrH2likcN6ZQ5DtWO7lt8 LxaPBYk/Fz8tGrfgtLbVsuoFGiDhVoqUc/47pi0v6IMtLjDHFfdTpZdMjxlKpmte y+9ePUrIh3vNr3xmZZFLfgp/nta5kkGlZQ+0sdQ9OfZdHtitpPRkph4= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Mail-Followup-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=mkAafdJfD1CJvQgtXzCKEik/T0X9QojpeY1/+KqUaGhfvFMFFLupZMHK1ctEr3 7tcqwjScvlXuv/d4WtrB2cZNte+DmeHgsYEajfcENvb+MTqpu+nfne1LvVkmclqc FXuS4LWxTdoZvEyvKO1N4OJg2HWrvCb5ggofDjCim+750=; Received: (qmail 25607 invoked by alias); 6 Feb 2013 13:38:46 -0000 Received: (qmail 25553 invoked by uid 22791); 6 Feb 2013 13:38:44 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pa0-f47.google.com (HELO mail-pa0-f47.google.com) (209.85.220.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 06 Feb 2013 13:38:38 +0000 Received: by mail-pa0-f47.google.com with SMTP id bj3so831227pad.34 for ; Wed, 06 Feb 2013 05:38:37 -0800 (PST) X-Received: by 10.66.73.138 with SMTP id l10mr75872872pav.44.1360157917189; Wed, 06 Feb 2013 05:38:37 -0800 (PST) Received: from bubble.grove.modra.org ([101.166.26.37]) by mx.google.com with ESMTPS id z10sm37836011pay.7.2013.02.06.05.38.34 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 Feb 2013 05:38:35 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id C67CAEA2F27; Thu, 7 Feb 2013 00:08:30 +1030 (CST) Date: Thu, 7 Feb 2013 00:08:30 +1030 From: Alan Modra To: gcc-patches@gcc.gnu.org Cc: David Edelsohn Subject: [RS6000] PR54009 again Message-ID: <20130206133830.GR5023@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org, David Edelsohn MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org My PR54131 fix caused PR54009 to raise its ugly head again. Allowing all LO_SUM addresses in the 'Y' constraint (mem_operand_gpr) wasn't quite correct. We still need to check for wrap when offsetting for multiple words/regs. Fixing that means the LO_SUM addresses not accepted by 'Y' need an address reload. OK assuming powerpc64 and powerpc-linux regression testing passes? PR target/54009 * config/rs6000/rs6000.c (mem_operand_gpr): Check that LO_SUM addresses won't wrap when offsetting. (rs6000_secondary_reload): Provide secondary reloads needed for wrapping LO_SUM addresses. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 195707) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -5135,17 +5135,14 @@ mem_operand_gpr if (TARGET_POWERPC64 && (offset & 3) != 0) return false; + extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD; + gcc_assert (extra >= 0); + 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; + /* For lo_sum addresses, we must allow any offset except one that + causes a wrap, so test only the low 16 bits. */ + offset = ((offset & 0xffff) ^ 0x8000) - 0x8000; - extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD; - gcc_assert (extra >= 0); return offset + 0x8000 < 0x10000u - extra; } @@ -13823,19 +13819,31 @@ rs6000_secondary_reload && MEM_P (x) && 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; + rtx addr = XEXP (x, 0); + rtx off = address_offset (addr); - if (off != NULL_RTX - && (INTVAL (off) & 3) != 0 - && (unsigned HOST_WIDE_INT) INTVAL (off) + 0x8000 < 0x10000 - extra) + if (off != NULL_RTX) { - if (in_p) - sri->icode = CODE_FOR_reload_di_load; + unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD; + unsigned HOST_WIDE_INT offset = INTVAL (off); + + /* We need a secondary reload when our legitimate_address_p + says the address is good (as otherwise the entire address + will be reloaded), and the offset is not a multiple of + four. */ + if ((GET_CODE (addr) == LO_SUM + || offset + 0x8000 < 0x10000 - extra) + && (offset & 3) != 0) + { + if (in_p) + sri->icode = CODE_FOR_reload_di_load; + else + sri->icode = CODE_FOR_reload_di_store; + sri->extra_cost = 2; + ret = NO_REGS; + } else - sri->icode = CODE_FOR_reload_di_store; - sri->extra_cost = 2; - ret = NO_REGS; + default_p = true; } else default_p = true; @@ -13845,25 +13853,43 @@ rs6000_secondary_reload && MEM_P (x) && 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; + rtx addr = XEXP (x, 0); + rtx off = address_offset (addr); - /* 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 - extra) - < UNITS_PER_WORD)) + if (off != NULL_RTX) { - if (in_p) - sri->icode = CODE_FOR_reload_si_load; + unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD; + unsigned HOST_WIDE_INT offset = INTVAL (off); + + /* We need a secondary reload when our legitimate_address_p + says the address is good (as otherwise the entire address + will be reloaded), and we have a wrap. + + legitimate_lo_sum_address_p allows LO_SUM addresses to + have any offset so test for wrap in the low 16 bits. + + legitimate_offset_address_p checks for the range + [-0x8000,0x7fff] for mode size of 8 and [-0x8000,0x7ff7] + for mode size of 16. We wrap at [0x7ffc,0x7fff] and + [0x7ff4,0x7fff] respectively, so test for the + intersection of these ranges, [0x7ffc,0x7fff] and + [0x7ff4,0x7ff7] respectively. + + Note that the address we see here may have been + manipulated by legitimize_reload_address. */ + if (GET_CODE (addr) == LO_SUM + ? ((offset & 0xffff) ^ 0x8000) >= 0x10000 - extra + : offset - (0x8000 - extra) < UNITS_PER_WORD) + { + if (in_p) + sri->icode = CODE_FOR_reload_si_load; + else + sri->icode = CODE_FOR_reload_si_store; + sri->extra_cost = 2; + ret = NO_REGS; + } else - sri->icode = CODE_FOR_reload_si_store; - sri->extra_cost = 2; - ret = NO_REGS; + default_p = true; } else default_p = true;