From patchwork Thu Aug 15 08:50:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1972703 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 4WkzNV0F9yz1yXZ for ; Thu, 15 Aug 2024 18:50:34 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C9A30385842C for ; Thu, 15 Aug 2024 08:50:31 +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 B9DB93858D34 for ; Thu, 15 Aug 2024 08:50:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B9DB93858D34 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 B9DB93858D34 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=1723711814; cv=none; b=QTOvLZs1YLpY8nR+U7iEkToKhmsu/ytomztx7k+C/n9bnvXFQPwlsfgjor3EL2I52m94itwQYJPHmvh/fo6AiK8njrFMjYWLQ4QUVOHz0GB2AIRmZnkcDRsOu5IthdlIkvhrQBVUqY41gQJGm3+RgA8Qpc9lYjcD2+Ygk2Ji8sg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1723711814; c=relaxed/simple; bh=ETtDsEWnVFeE6VsVOBvVdGCfse27SgL6lSgcmSjn5E4=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=S0Sv7Qqg7W8Qbt+AJz+u8yZFWX+Q0W0QWMA8lMfOCeSqRPj8EQr3RytGipW5HmnghSoxMbL0V6PdGuMOR9wMOnfrJeERRmAd3ursByAYDOeCqLN5xTn/FWn4GxEKwUlDWJacZHdXDS4p6d1RhGc8zjmq2G81mv0VUqlUcME7NaY= 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 735AB169E for ; Thu, 15 Aug 2024 01:50:38 -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 2E7713F6A8 for ; Thu, 15 Aug 2024 01:50:12 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH] Tweak base/index disambiguation in decompose_normal_address [PR116236] Date: Thu, 15 Aug 2024 09:50:10 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Spam-Status: No, score=-19.0 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 PR points out that, for an address like: (plus (zero_extend X) Y) decompose_normal_address doesn't establish a strong preference between treating X as the base or Y as the base. As the comment in the patch says, zero_extend isn't enough on its own to assume an index, at least not on POINTERS_EXTEND_UNSIGNED targets. But in a construct like the one above, X and Y have different modes, and it seems reasonable to assume that the one with the expected address mode is the base. This matters on targets like m68k that support index extension and that require different classes for bases and indices. Tested on aarch64-linux-gnu & x86_64-linux-gnu. Andreas also confirms that it fixes the m68k LRA problem. OK to install? Richard gcc/ PR middle-end/116236 * rtlanal.cc (decompose_normal_address): Try to distinguish bases and indices based on mode, before resorting to "baseness". --- gcc/rtlanal.cc | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 4158a531bdd..71207ee4f41 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -6724,20 +6724,36 @@ decompose_normal_address (struct address_info *info) } else if (out == 2) { + auto address_mode = targetm.addr_space.address_mode (info->as); + rtx inner_op0 = *inner_ops[0]; + rtx inner_op1 = *inner_ops[1]; + int base; + /* If one inner operand has the expected mode for a base and the other + doesn't, assume that the other one is the index. This is useful + for addresses such as: + + (plus (zero_extend X) Y) + + zero_extend is not in itself enough to assume an index, since bases + can be zero-extended on POINTERS_EXTEND_UNSIGNED targets. But if + Y has address mode and X doesn't, there should be little doubt that + Y is the base. */ + if (GET_MODE (inner_op0) == address_mode + && GET_MODE (inner_op1) != address_mode) + base = 0; + else if (GET_MODE (inner_op1) == address_mode + && GET_MODE (inner_op0) != address_mode) + base = 1; /* In the event of a tie, assume the base comes first. */ - if (baseness (*inner_ops[0], info->mode, info->as, PLUS, - GET_CODE (*ops[1])) - >= baseness (*inner_ops[1], info->mode, info->as, PLUS, - GET_CODE (*ops[0]))) - { - set_address_base (info, ops[0], inner_ops[0]); - set_address_index (info, ops[1], inner_ops[1]); - } + else if (baseness (inner_op0, info->mode, info->as, PLUS, + GET_CODE (*ops[1])) + >= baseness (inner_op1, info->mode, info->as, PLUS, + GET_CODE (*ops[0]))) + base = 0; else - { - set_address_base (info, ops[1], inner_ops[1]); - set_address_index (info, ops[0], inner_ops[0]); - } + base = 1; + set_address_base (info, ops[base], inner_ops[base]); + set_address_index (info, ops[1 - base], inner_ops[1 - base]); } else gcc_assert (out == 0);