From patchwork Mon Jul 29 10:38:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1965931 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 4WXZbW0JH3z1yYq for ; Mon, 29 Jul 2024 20:39:02 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0603F385841C for ; Mon, 29 Jul 2024 10:39: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 C95053858D37 for ; Mon, 29 Jul 2024 10:38:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C95053858D37 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 C95053858D37 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=1722249508; cv=none; b=nV1Jz9fL4Fqml/Pic5MY+/vk1q4tGD1bW6N1SUlGhBciyzWylXP+FyoBjfJDcX2xyAvNox3B7trgtZGmHWi0JIXwTJqZ2YYXUkEP3prEDeYaaNfQ4fW4L257vyDGn5kX15P8cNa00Zj5utXDfdQXJ/Act2XY8S7vBbKZ1SRWJYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722249508; c=relaxed/simple; bh=2sn2YVZ9R6FtSenZ0NkvrD/+iNQlp98u+nbZgdP2rwk=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=puDos+QHXYTimY3soa5hfxgFcJKTXI2pLJ+gVrB4Hq6Plimq8UcKNqV2jMHdKXf3HkzHREz2eg76S3GMU6oUFQmxmucmk/X21vDlD1pMZbmUQNQxGfhiKKxyJj2+4mONZv0eFOoGQc0bSpOivC9PDKwF4ZSarxrPmfPpnTLThzo= 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 DB3A81007 for ; Mon, 29 Jul 2024 03:38:50 -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 EEEAD3F64C for ; Mon, 29 Jul 2024 03:38:24 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Ping: [PATCH] recog: Disallow subregs in mode-punned value [PR115881] In-Reply-To: (Richard Sandiford's message of "Fri, 19 Jul 2024 18:37:37 +0100") References: Date: Mon, 29 Jul 2024 11:38:23 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Spam-Status: No, score=-19.2 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 Ping Richard Sandiford writes: > 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); +}