From patchwork Mon Aug 2 20:24:25 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 60656 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 67A85B70AA for ; Tue, 3 Aug 2010 06:29:26 +1000 (EST) Received: (qmail 4193 invoked by alias); 2 Aug 2010 20:25:08 -0000 Received: (qmail 3960 invoked by uid 22791); 2 Aug 2010 20:24:58 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, TW_ZJ, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Received: from mailout11.t-online.de (HELO mailout11.t-online.de) (194.25.134.85) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 02 Aug 2010 20:24:47 +0000 Received: from fwd00.aul.t-online.de (fwd00.aul.t-online.de ) by mailout11.t-online.de with smtp id 1Og1Yy-0001RJ-9X; Mon, 02 Aug 2010 22:24:44 +0200 Received: from [84.152.249.133] (bLs-tYZDYhY6yoDdxEQ6G0+ytQ2qRaZvFkJsIfGr6n39gpjp3RJ7TDrqUMwdAu3QlZ@[84.152.249.133]) by fwd00.aul.t-online.de with esmtp id 1Og1Ym-0F8Vv60; Mon, 2 Aug 2010 22:24:32 +0200 Message-ID: <4C572979.5020303@t-online.de> Date: Mon, 02 Aug 2010 22:24:25 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.7) Gecko/20100724 Thunderbird/3.1.1 MIME-Version: 1.0 To: GCC Patches Subject: Fix target/45063, caller-save.c problem induced by IRA multiword changes 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 After the IRA changes to track words separately, the same hard register may appear to hold more than one live pseudo. This confuses caller-save.c into turning (... reg:DI 18 is used ...) call somehwere ;; clobber reg:DI 18 set (reg:SI 19) something else use (reg:SI 19) into (... reg:DI 18 is used ...) save reg:DI 18 call somehwere ;; clobber reg:DI 18 set (reg:SI 19) something else restore REG:SI 19 ;; because the next insn uses it... use (reg:SI 19) Fixed by making it look for stores into regs it thinks it still has to restore. There's comment elsewhere in caller-save already which describes a similar problem: /* Record all registers set in this call insn. These don't need to be saved. N.B. the call insn might set a subreg of a multi-hard-reg pseudo; then the pseudo is considered live during the call, but the subreg that is set isn't. */ For a while I was worried that there might be other places in reload which could be confused, until I found /* Similarly, only do this if we can be sure that the death note is still valid. global can assign some hardreg to the pseudo referenced in the note and simultaneously a subword of this hardreg to a different, also live pseudo, because only another subword of the hardreg is actually used in the insn. This cannot happen if the pseudo has been assigned exactly one hardreg. See PR 33732. */ and remembered that the IRA change isn't actually a new thing, just a regression fix for something local-alloc was able to do for a long time. Bootstrapped and regression tested on i686-linux; committed. It's been reported to fix the PA bootstrap problem. Bernd Index: ChangeLog =================================================================== --- ChangeLog (revision 162827) +++ ChangeLog (working copy) @@ -1,3 +1,9 @@ +2010-08-02 Bernd Schmidt + + PR target/45063 + * caller-save.c (save_call_clobbered_regs): Remove regs from + hard_regs_saved when they are set. + 2010-08-02 Uros Bizjak PR target/41089 Index: caller-save.c =================================================================== --- caller-save.c (revision 162821) +++ caller-save.c (working copy) @@ -763,6 +763,7 @@ save_call_clobbered_regs (void) if (n_regs_saved) { int regno; + HARD_REG_SET this_insn_sets; if (code == JUMP_INSN) /* Restore all registers if this is a JUMP_INSN. */ @@ -777,7 +778,17 @@ save_call_clobbered_regs (void) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (referenced_regs, regno)) - regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode); + regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, + save_mode); + /* If a saved register is set after the call, this means we no + longer should restore it. This can happen when parts of a + multi-word pseudo do not conflict with other pseudos, so + IRA may allocate the same hard register for both. One may + be live across the call, while the other is set + afterwards. */ + CLEAR_HARD_REG_SET (this_insn_sets); + note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets); } if (code == CALL_INSN