From patchwork Thu Aug 22 08:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1975358 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WqGx95qWlz1yYZ for ; Thu, 22 Aug 2024 18:45:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 87EB23870C21 for ; Thu, 22 Aug 2024 08:45:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 733313870C13 for ; Thu, 22 Aug 2024 08:44:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 733313870C13 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 733313870C13 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724316289; cv=none; b=lnzg8y4G6m/5mT/iBfhdkmLGAe7IsqluZxraYMGVr1khKG4md1oANscvTjiUUXW4S33k15UuhCtFO7j/JQSYmUHevJFELE2FeUxeQrcXb0l6n/Fm2QIgLKcWz9d73ehVb3X2XsFYg/ArOW/5IFKgyGDS2QE6IY4/9s/OqF7qCmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724316289; c=relaxed/simple; bh=Eq+aMDCjFB4hcR66COMgirVF2upNgnELU2JoeSJUhKs=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=hvZXVtulr+/VHBRE+oUuTfp4RenL9+wYfvASDP6qTIQe+f75rhlW9nGJJ/b8g8APvMcJWmKldOmJdXFDFPav9n9NhF9gn1qt/FZft5XteUz+W/8w8TuD7ob84HPqL0zmQaLpqOT9pPhDwx4rWq8YBb9n2oKDLOCjOHGZnlMkmSA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 46804DA7; Thu, 22 Aug 2024 01:45:13 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 730753F66E; Thu, 22 Aug 2024 01:44:46 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org,vmakarov@redhat.com, jeffreyalaw@gmail.com, richard.sandiford@arm.com Cc: vmakarov@redhat.com, jeffreyalaw@gmail.com Subject: [PATCH] lra: Don't apply eliminations to allocated registers [PR116321] Date: Thu, 22 Aug 2024 09:44:44 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Spam-Status: No, score=-18.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org The sequence of events in this PR is that: - the function has many addresses in which only a single hard base register is acceptable. Let's call the hard register H. - IRA allocates that register to one of the pseudo base registers. Let's call the pseudo register P. - Some of the other addresses that require H occur when P is still live. - LRA therefore has to spill P. - When it reallocates P, LRA chooses to use FRAME_POINTER_REGNUM, which has been eliminated to the stack pointer. (This is ok, since the frame register is free.) - Spilling P causes LRA to reprocess the instruction that uses P. - When reprocessing the address that has P as its base, LRA first applies the new allocation, to get FRAME_POINTER_REGNUM, and then applies the elimination, to get the stack pointer. The last step seems wrong: the elimination should only apply to pre-existing uses of FRAME_POINTER_REGNUM, not to uses that result from allocating pseudos. Applying both means that we get the wrong register number, and therefore the wrong class. The PR is about an existing testcase that fails with LRA on m86k. Tested on aarch64-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu. Also tested by building at least one target per CPU directory and checking that there were no asm changes or new ICEs when compiling gcc.c-torture, gcc.dg, and g++.dg at -Os. OK to install? Richard gcc/ PR middle-end/116321 * lra-constraints.cc (get_hard_regno): Only apply eliminations to existing hard registers. (get_reg_class): Likewise. --- gcc/lra-constraints.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 90cbe6c012b..fdcc07764a2 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -200,12 +200,13 @@ get_hard_regno (rtx x) reg = SUBREG_REG (x); if (! REG_P (reg)) return -1; - if (! HARD_REGISTER_NUM_P (hard_regno = REGNO (reg))) - hard_regno = lra_get_regno_hard_regno (hard_regno); + int regno = REGNO (reg); + if (HARD_REGISTER_NUM_P (regno)) + hard_regno = lra_get_elimination_hard_regno (regno); + else + hard_regno = lra_get_regno_hard_regno (regno); if (hard_regno < 0) return -1; - if (HARD_REGISTER_NUM_P (REGNO (reg))) - hard_regno = lra_get_elimination_hard_regno (hard_regno); if (SUBREG_P (x)) hard_regno += subreg_regno_offset (hard_regno, GET_MODE (reg), SUBREG_BYTE (x), GET_MODE (x)); @@ -221,13 +222,12 @@ get_reg_class (int regno) { int hard_regno; - if (! HARD_REGISTER_NUM_P (hard_regno = regno)) + if (HARD_REGISTER_NUM_P (regno)) + hard_regno = lra_get_elimination_hard_regno (regno); + else hard_regno = lra_get_regno_hard_regno (regno); if (hard_regno >= 0) - { - hard_regno = lra_get_elimination_hard_regno (hard_regno); - return REGNO_REG_CLASS (hard_regno); - } + return REGNO_REG_CLASS (hard_regno); if (regno >= new_regno_start) return lra_get_allocno_class (regno); return NO_REGS;