From patchwork Tue Jun 28 13:47:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 102382 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 F1C46B6F72 for ; Tue, 28 Jun 2011 23:47:53 +1000 (EST) Received: (qmail 17595 invoked by alias); 28 Jun 2011 13:47:50 -0000 Received: (qmail 17469 invoked by uid 22791); 28 Jun 2011 13:47:48 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 28 Jun 2011 13:47:34 +0000 Received: by qwh5 with SMTP id 5so120588qwh.20 for ; Tue, 28 Jun 2011 06:47:34 -0700 (PDT) MIME-Version: 1.0 Received: by 10.224.219.10 with SMTP id hs10mr5716816qab.80.1309268853925; Tue, 28 Jun 2011 06:47:33 -0700 (PDT) Received: by 10.229.214.83 with HTTP; Tue, 28 Jun 2011 06:47:33 -0700 (PDT) In-Reply-To: References: <201106272208.p5RM8EKX020141@d06av02.portsmouth.uk.ibm.com> Date: Tue, 28 Jun 2011 06:47:33 -0700 Message-ID: Subject: Re: PATCH [10/n]: Prepare x32: PR rtl-optimization/49114: Reload failed to handle (set reg:X (plus:X (subreg:X (reg:Y) 0) (const From: "H.J. Lu" To: Ulrich Weigand Cc: gcc-patches@gcc.gnu.org, bernds@codesourcery.com 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 On Mon, Jun 27, 2011 at 3:25 PM, H.J. Lu wrote: > On Mon, Jun 27, 2011 at 3:19 PM, H.J. Lu wrote: >> On Mon, Jun 27, 2011 at 3:08 PM, Ulrich Weigand wrote: >>> H.J. Lu wrote: >>> >>>> reload generates: >>>> >>>> (insn 914 912 0 (set (reg:SI 0 ax) >>>>         (plus:SI (subreg:SI (reg/v/f:DI 182 [ b ]) 0) >>>>             (const_int 8 [0x8]))) 248 {*lea_1_x32} >>>>      (nil)) >>>> >>>> from >>>> >>>> insn = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in)); >>> >>> Interesting.  The pseudo should have been replaced by the >>> hard register (reg:DI 1) during the preceding call to >>>      op0 = find_replacement (&XEXP (in, 0)); >>> (since reload 0 should have pushed a replacement record.) >>> >>> Interestingly enough, in the final output that replacement *is* >>> performed in the REG_EQUIV note: >>> >>> (insn 1023 1022 1024 34 (set (reg:SI 1 dx) >>>        (plus:SI (reg:SI 1 dx) >>>            (const_int 8 [0x8]))) spooles.c:291 248 {*lea_1_x32} >>>     (expr_list:REG_EQUIV (plus:SI (subreg:SI (reg:DI 1 dx) 0) >>>            (const_int 8 [0x8])) >>>        (nil))) >>> >>> which is why I hadn't expected this to be a problem here. >>> >>> Can you try to find out why the find_replacement doesn't work >>> with your test case? >>> >> >> I will investigate.  Could (reg:SI 1 dx) vs  (subreg:SI (reg:DI 1 dx) 0) >> a problem? >> > > find_replacement never checks subreg: > > Breakpoint 3, find_replacement (loc=0x7ffff068ab00) >    at /export/gnu/import/git/gcc-x32/gcc/reload.c:6411 > 6411          if (reloadreg && r->where == loc) > (reg:DI 0 ax) > (reg/v/f:DI 182 [ b ]) > (gdb) call debug_rtx (*loc) > (subreg:SI (reg/v/f:DI 182 [ b ]) 0) > (gdb) > This patch checks SUBREG pointer if Pmode != ptr_mode. OK for trunk? Thanks. diff --git a/gcc/reload.c b/gcc/reload.c index 3ad46b9..829e45b 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6415,6 +6415,36 @@ find_replacement (rtx *loc) return reloadreg; } + else if (Pmode != ptr_mode + && !r->subreg_loc + && reloadreg + && (r->mode == Pmode || GET_MODE (reloadreg) == Pmode) + && REG_P (reloadreg) + && GET_CODE (*loc) == SUBREG + && REG_P (SUBREG_REG (*loc)) + && REG_POINTER (SUBREG_REG (*loc)) + && GET_MODE (*loc) == ptr_mode + && r->where == &SUBREG_REG (*loc)) + { + int offset; + + if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode) + reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg)); + + if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) + && GET_MODE_SIZE (Pmode) > GET_MODE_SIZE (ptr_mode)) + { + offset = GET_MODE_SIZE (Pmode) - GET_MODE_SIZE (ptr_mode); + if (! BYTES_BIG_ENDIAN) + offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; + else if (! WORDS_BIG_ENDIAN) + offset %= UNITS_PER_WORD; + } + else + offset = 0; + + return gen_rtx_SUBREG (ptr_mode, reloadreg, offset); + } else if (reloadreg && r->subreg_loc == loc) { /* RELOADREG must be either a REG or a SUBREG.