From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 108620 invoked by alias); 23 Sep 2015 12:16:44 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 108538 invoked by uid 48); 23 Sep 2015 12:16:40 -0000 From: "vogt at linux dot vnet.ibm.com" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/61578] [4.9 regression] Code size increase for ARM thumb compared to 4.8.x when compiling with -Os Date: Wed, 23 Sep 2015 12:16:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 4.9.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: vogt at linux dot vnet.ibm.com X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 4.9.4 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-09/txt/msg01867.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61578 --- Comment #29 from Dominik Vogt --- I think I understand what's going on: Consider the patched code in match_reloads(): + = (ins[1] < 0 && REG_P (in_rtx) + && (int) REGNO (in_rtx) < lra_new_regno_start + && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx)) + ? lra_create_new_reg (inmode, in_rtx, goal_class, "") + : lra_create_new_reg_with_unique_value (outmode, out_rtx, + goal_class, "")); (1) This code normally makes a unique copy of the register in in_rtx, but if the register is marked as REG_DEAD in the curr_insn, it just makes a copy of the register using lra_create_new_reg(), with the same .val and .offset in the reg_info structure. (2) Further down in match_reloads, new insns are generated and stored in *before and *after. However, the new "after" insn still references the old register. In other words, in step (1) the code has made the assumption that the old register is no longer used, then generates an insn that uses it after it was marked as REG_DEAD. (3) Based on the bogus decision in (1), the condition in lra-lives.c decides that the two registers are identical copies and can be mapped to the same hard register: + && (((src_regno >= FIRST_PSEUDO_REGISTER + && (! sparseset_bit_p (pseudos_live, src_regno) + || (dst_regno >= FIRST_PSEUDO_REGISTER + && lra_reg_val_equal_p (src_regno, + lra_reg_info[dst_regno].val, + lra_reg_info[dst_regno].offset))