From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20933 invoked by alias); 2 Apr 2009 10:52:04 -0000 Received: (qmail 20924 invoked by uid 22791); 2 Apr 2009 10:52:03 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail-fx0-f165.google.com (HELO mail-fx0-f165.google.com) (209.85.220.165) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 02 Apr 2009 10:51:58 +0000 Received: by fxm9 with SMTP id 9so457096fxm.8 for ; Thu, 02 Apr 2009 03:51:55 -0700 (PDT) MIME-Version: 1.0 Received: by 10.223.108.196 with SMTP id g4mr7134879fap.36.1238669515159; Thu, 02 Apr 2009 03:51:55 -0700 (PDT) In-Reply-To: <20090401133434.GB23688@elsdt-razorfish.arc.com> References: <20090401133434.GB23688@elsdt-razorfish.arc.com> Date: Thu, 02 Apr 2009 10:52:00 -0000 Message-ID: <5787cf470904020351ve8a375bq455a31c185443f82@mail.gmail.com> Subject: Re: Invalid reload inheritance with paradoxical subregs From: Uros Bizjak To: Joern Rennecke Cc: GCC Development Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2009-04/txt/msg00087.txt.bz2 On Wed, Apr 1, 2009 at 3:34 PM, Joern Rennecke wrote: > I suggest you first find out more what is exactly reloaded and where > the inheritance occurs - inheritance can be done by choose_reload_regs > or later in emit_reload_insns and its subfunctions. > > I.e. set a breakpoint on find_reloads and make it conditional on > insn->u.fld[0].rt_int == 121 && replace > , let the compilation break there, finish, and call debug_reload() > to look at the scheduled reloads. > Then set a breakpoint on choose_reload_regs, make it conditional on > chain->insn->u.fld[0].rt_int == 121 > , continue to the breakpoint, finish, and call debug_reload() again. > This should tell you what MEM is actually reloaded, and if the inheritance > already happens there; depending on what you find, you have to look further > in choose_reload_regs or in the reload emitting code. Joern, thans for your detailed instructions. I think I found, where problem is: Combine simplifies lshiftrt/shift/and combined instruction under the assumption, that for ZERO_EXTEND LOAD_EXTEND_OP targets it can prove that certain bits are zero, so AND operation can be omitted. The resulting instruction is valid only for memory operand: (gdb) p debug_rtx (insn) (insn 121 120 125 2 t.c:22 (set (reg:SI 6 r6 [orig:48 y$k.115 ] [48]) (lshiftrt:SI (subreg:SI (mem/s/c:HI (plus:SI (reg/f:SI 1 r1) (const_int 16 [0x10])) [0+4 S2 A32]) 0) (const_int 5 [0x5]))) 62 {lshrsi3} (nil)) Now, tracing this instruction through reload_as_needed () function, we have following reloads just after the call to choose_reload_regs (...): (gdb) p debug_reload () Reload 0: reload_in (HI) = (mem/s/c:HI (plus:SI (reg/f:SI 1 r1) (const_int 16 [0x10])) [0+4 S2 A32]) GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1) reload_in_reg: (mem/s/c:HI (plus:SI (reg/f:SI 1 r1) (const_int 16 [0x10])) [0+4 S2 A32]) reload_reg_rtx: (reg:HI 7 r7) This is all correct, until subst_reloads (...) is called a coouple of lines down the source. This call changes (insn 121) to: (gdb) p debug_rtx (insn) (insn 121 120 125 2 t.c:22 (set (reg:SI 6 r6 [orig:48 y$k.115 ] [48]) (lshiftrt:SI (subreg:SI (reg:HI 7 r7) 0) (const_int 5 [0x5]))) 62 {lshrsi3} (nil)) This substitution is wrong. Paradoxical subreg of a memory operand is for our target known to zero extend to SImode value, however - paradoxical subreg of a register operand has undefined bits outside the reg. So, combine and reload doesn't agree on the bits outside the register. After this substitution, subreg RTX is simply stripped away via the call to cleanup_subreg_operands () in reload () and that leaves us with undefined bits shifted in. I guess that somehow we have to prevent choose_reload_regs to blindly substitute memory_operand with register when paradoxical subregs are involved. The condition for the substitution should be similar to the condition in nonzero_bits1 from final.c: #if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP) /* If this is a typical RISC machine, we only have to worry about the way loads are extended. */ if ((LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND ? (((nonzero & (((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - 1)))) != 0)) : LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) != ZERO_EXTEND) || !MEM_P (SUBREG_REG (x))) #endif Uros.