From patchwork Thu Apr 7 10:47:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 90156 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 91D94B6F44 for ; Thu, 7 Apr 2011 20:48:01 +1000 (EST) Received: (qmail 3255 invoked by alias); 7 Apr 2011 10:47:59 -0000 Received: (qmail 3245 invoked by uid 22791); 7 Apr 2011 10:47:57 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 07 Apr 2011 10:47:53 +0000 Received: (qmail 21291 invoked from network); 7 Apr 2011 10:47:51 -0000 Received: from unknown (HELO ?84.152.173.207?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 7 Apr 2011 10:47:51 -0000 Message-ID: <4D9D963B.7070001@codesourcery.com> Date: Thu, 07 Apr 2011 12:47:23 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110325 Lightning/1.0b3pre Thunderbird/3.1.9 MIME-Version: 1.0 To: GCC Patches CC: Andrew Stubbs Subject: Fix PR47976 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 PR47976 is a followup to PR47166; the patch there caused this problem. The problem occurs in reload. There are two autoinc addresses which inherit from one another, and we delete an insn that is necessary. We reach this code when reloading the second autoinc address: 6821 if (optimize && REG_P (oldequiv) 6822 && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER 6823 && spill_reg_store[REGNO (oldequiv)] 6824 && REG_P (old) (gdb) 6825 && (dead_or_set_p (insn, 6826 spill_reg_stored_to[REGNO (oldequiv)]) 6827 || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)], 6828 old))) 6829 delete_output_reload (insn, j, REGNO (oldequiv), reloadreg); reload_inherited[j] is 1 at this point, so oldequiv == reloadreg. (gdb) p debug_rtx (spill_reg_store[7]) (insn 719 718 232 10 (set (reg:SI 7 r7) (reg:SI 3 r3 [orig:339 ivtmp.79 ] [339])) -1 (nil)) (gdb) p debug_rtx (spill_reg_stored_to[7]) (reg:SI 3 r3) Prior to the PR47166 patch, we had spill_reg_store[7] equal to insn 718, which doesn't involve register 7 at all: (insn 718 221 719 10 (set (reg:SI 3 r3 [orig:339 ivtmp.79 ] [339]) (plus:SI (reg:SI 3 r3 [orig:339 ivtmp.79 ] [339]) (const_int 8 [0x8]))) 4 {*arm_addsi3} (nil)) That was sufficient to generate enough confusion to make the compiler think it couldn't delete the output reload. I think the problem is simply that the (set (r7) (r3)) is the opposite direction of a normal spill_reg_store - normally you write a spill reg to its destination, but autoinc reloads are somewhat special. If delete_output_reload isn't valid for (at least some) autoincs, we can simply not record them in spill_reg_store. That's part of the patch below; it seems to fix the problem. I've also deleted the code quoted above since it's pointless to have reload deleting dead stores to registers: that's what DCE is for. I've observed no code generation changes other than for the testcase from either of these changes, with both an ARM and an sh compiler. Comments? Bernd PR fortran/47976 * reload1.c (inc_for_reload): Return void. All callers changed. (emit_input_reload_insns): Don't try to delete previous output reloads to a register, or record spill_reg_store for autoincs. Index: reload1.c =================================================================== --- reload1.c (revision 170053) +++ reload1.c (working copy) @@ -457,7 +457,7 @@ static void emit_reload_insns (struct in static void delete_output_reload (rtx, int, int, rtx); static void delete_address_reloads (rtx, rtx); static void delete_address_reloads_1 (rtx, rtx, rtx); -static rtx inc_for_reload (rtx, rtx, rtx, int); +static void inc_for_reload (rtx, rtx, rtx, int); #ifdef AUTO_INC_DEC static void add_auto_inc_notes (rtx, rtx); #endif @@ -6818,22 +6818,12 @@ emit_input_reload_insns (struct insn_cha old = XEXP (rl->in_reg, 0); - if (optimize && REG_P (oldequiv) - && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER - && spill_reg_store[REGNO (oldequiv)] - && REG_P (old) - && (dead_or_set_p (insn, - spill_reg_stored_to[REGNO (oldequiv)]) - || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)], - old))) - delete_output_reload (insn, j, REGNO (oldequiv), reloadreg); - /* Prevent normal processing of this reload. */ special = 1; - /* Output a special code sequence for this case. */ - new_spill_reg_store[REGNO (reloadreg)] - = inc_for_reload (reloadreg, oldequiv, rl->out, - rl->inc); + /* Output a special code sequence for this case, and forget about + spill reg information. */ + new_spill_reg_store[REGNO (reloadreg)] = NULL; + inc_for_reload (reloadreg, oldequiv, rl->out, rl->inc); } /* If we are reloading a pseudo-register that was set by the previous @@ -8643,11 +8633,9 @@ delete_address_reloads_1 (rtx dead_insn, IN is either identical to VALUE, or some cheaper place to reload from. INC_AMOUNT is the number to increment or decrement by (always positive). - This cannot be deduced from VALUE. - - Return the instruction that stores into RELOADREG. */ + This cannot be deduced from VALUE. */ -static rtx +static void inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount) { /* REG or MEM to be copied and incremented. */ @@ -8707,9 +8695,8 @@ inc_for_reload (rtx reloadreg, rtx in, r be used as an address. */ if (! post) - add_insn = emit_insn (gen_move_insn (reloadreg, incloc)); - - return add_insn; + emit_insn (gen_move_insn (reloadreg, incloc)); + return; } } delete_insns_since (last); @@ -8745,8 +8732,6 @@ inc_for_reload (rtx reloadreg, rtx in, r else emit_insn (gen_sub2_insn (reloadreg, inc)); } - - return store; } #ifdef AUTO_INC_DEC