From patchwork Fri Jul 19 17:37:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1962579 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=8.43.85.97; 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 [8.43.85.97]) (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 4WQcMb6BDyz1ySl for ; Sat, 20 Jul 2024 03:38:03 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B516D3860761 for ; Fri, 19 Jul 2024 17:38:01 +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 03C743860761 for ; Fri, 19 Jul 2024 17:37:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 03C743860761 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 03C743860761 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=1721410661; cv=none; b=uDJWDmiOohn1tYBV+ND8EOufvuWVzBndwP/zPTEng8qzS2S4fDbatmfzLOWjZWQpoe3K0DbyOGWi0mLazJ9VghqaE2dmHQYYwmwgbG8PnkAn7bbCqu7FY6JCM5fwTsCYgkbHUW12X7MeIhkg17HBOZyrT+Klc6+TXhl1+TK34kk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721410661; c=relaxed/simple; bh=8NhYbjkmkkzZukNqFVFpysslZi4tTME0uZGf2Uhza74=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=AGaVB1bns3+JgNVoWcKWoZW0Ppk2uSwRLJDcd9K+FlMJyOF1/pEHgzbiKwN8ohyTBEfpR1QkUTfXgzth9E4JZl1h+K62b3+nCZaCnx6FwVD5lo/uuPrUQmm7R5yxxYftef89QaQsanKb77zhacq3xF/pKQrV6skZX6FLUx/A8Ss= 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 031C7169E for ; Fri, 19 Jul 2024 10:38:04 -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 4A7E73F762 for ; Fri, 19 Jul 2024 10:37:38 -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] recog: Disallow subregs in mode-punned value [PR115881] Date: Fri, 19 Jul 2024 18:37:37 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Spam-Status: No, score=-19.3 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 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 In g:9d20529d94b23275885f380d155fe8671ab5353a, I'd extended insn_propagation to handle simple cases of hard-reg mode punning. The punned "to" value was created using simplify_subreg rather than simplify_gen_subreg, on the basis that hard-coded subregs aren't generally useful after RA (where hard-reg propagation is expected to happen). This PR is about a case where the subreg gets pushed into the operands of a plus, but the subreg on one of the operands cannot be simplified. Specifically, we have to generate (subreg:SI (reg:DI sp) 0) rather than (reg:SI sp), since all references to the stack pointer must be via stack_pointer_rtx. However, code in x86 (reasonably) expects no subregs of registers to appear after RA, except for special cases like strict_low_part. This leads to an awkward situation where we can't ban subregs of sp (because of the strict_low_part use), can't allow direct references to sp in other modes (because of the stack_pointer_rtx requirement), and can't allow rvalue uses of the subreg (because of the "no subregs after RA" assumption). It all seems a bit of a mess... I sat on this for a while in the hope that a clean solution might become apparent, but in the end, I think we'll just have to check manually for nested subregs and punt on them. Tested on aarch64-linux-gnu & x86_64-linux-gnu. OK to install? Richard gcc/ PR rtl-optimization/115881 * recog.cc: Include rtl-iter.h. (insn_propagation::apply_to_rvalue_1): Check that the result of simplify_subreg does not include nested subregs. gcc/tetsuite/ PR rtl-optimization/115881 * cc.c-torture/compile/pr115881.c: New test. --- gcc/recog.cc | 21 +++++++++++++++++++ .../gcc.c-torture/compile/pr115881.c | 16 ++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr115881.c diff --git a/gcc/recog.cc b/gcc/recog.cc index 54b317126c2..23e4820180f 100644 --- a/gcc/recog.cc +++ b/gcc/recog.cc @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "reload.h" #include "tree-pass.h" #include "function-abi.h" +#include "rtl-iter.h" #ifndef STACK_POP_CODE #if STACK_GROWS_DOWNWARD @@ -1082,6 +1083,7 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc) || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from), GET_MODE (x))) return false; + /* If the reference is paradoxical and the replacement value contains registers, we would need to check that the simplification below does not increase REG_NREGS for those @@ -1090,11 +1092,30 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc) if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (from)) && !CONSTANT_P (to)) return false; + newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from), subreg_lowpart_offset (GET_MODE (x), GET_MODE (from))); if (!newval) return false; + + /* Check that the simplification didn't just push an explicit + subreg down into subexpressions. In particular, for a register + R that has a fixed mode, such as the stack pointer, a subreg of: + + (plus:M (reg:M R) (const_int C)) + + would be: + + (plus:N (subreg:N (reg:M R) ...) (const_int C')) + + But targets can legitimately assume that subregs of hard registers + will not be created after RA (except in special circumstances, + such as strict_low_part). */ + subrtx_iterator::array_type array; + FOR_EACH_SUBRTX (iter, array, newval, NONCONST) + if (GET_CODE (*iter) == SUBREG) + return false; } if (should_unshare) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr115881.c b/gcc/testsuite/gcc.c-torture/compile/pr115881.c new file mode 100644 index 00000000000..8379704c4c8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr115881.c @@ -0,0 +1,16 @@ +typedef unsigned u32; +int list_is_head(); +void tu102_acr_wpr_build_acr_0_0_0(int, long, u32); +void tu102_acr_wpr_build() { + u32 offset = 0; + for (; list_is_head();) { + int hdr; + u32 _addr = offset, _size = sizeof(hdr), *_data = &hdr; + while (_size--) { + tu102_acr_wpr_build_acr_0_0_0(0, _addr, *_data++); + _addr += 4; + } + offset += sizeof(hdr); + } + tu102_acr_wpr_build_acr_0_0_0(0, offset, 0); +}