From patchwork Tue Jan 30 09:33:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1892722 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 4TPKkX46sLz23dQ for ; Tue, 30 Jan 2024 20:34:28 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 92EB53857C67 for ; Tue, 30 Jan 2024 09:34:26 +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 3BA723857C5E for ; Tue, 30 Jan 2024 09:33:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3BA723857C5E 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 3BA723857C5E 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=1706607200; cv=none; b=Kits1GN51T5SELUyF6dWGgwcM9a5C6qo/acPYpy6nrlU0Pv540HefEh3S29c10qV/PJF9Fr4Fjx0dD+7j/Y2yA9vVXwZqbXeNXuJtXHwUM02rGgb19cZEKn2Mu33nY7r4+UERnA4oCnxB1nYvSsSXeuCE6nsOaBSEFB3GTrcAAU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706607200; c=relaxed/simple; bh=WHt0qjTI8vkEPkfSsV+bhjlZwL8Kb++55FrnBlPqxes=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=Sl2DFeDo8rkBJprX+JEixgcaGKtUpsSn6VlzRmDHLhXjOQqJPWJCWTwRF7SUctijAWnDoT8S2sYR9qC20QIbCb4qhb1KvjuumFOASzcSsoJZ+r42i5Z153uO9gKnxrDfsMHcnFD+mk0DVZkZpLx6FD8wNiq1FtL0XF7kvfecnk0= 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 6271ADA7 for ; Tue, 30 Jan 2024 01:34:00 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 568FC3F738 for ; Tue, 30 Jan 2024 01:33:16 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [pushed] aarch64: Handle debug references to removed registers [PR113636] Date: Tue, 30 Jan 2024 09:33:15 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Spam-Status: No, score=-21.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, 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 In this PR, we entered early-ra with quite a bit of dead code. The code was duly removed (to avoid wasting registers), but there was a dangling reference in debug instructions, which caused an ICE later. Fixed by resetting a debug instruction if it references a register that is no longer needed by non-debug instructions. Tested on aarch64-linux-gnu & pushed. Richard gcc/ PR target/113636 * config/aarch64/aarch64-early-ra.cc (early_ra::replace_regs): Take the containing insn as an extra parameter. Reset debug instructions if they reference a register that is no longer used by real insns. (early_ra::apply_allocation): Update calls accordingly. gcc/testsuite/ PR target/113636 * go.dg/pr113636.go: New test. --- gcc/config/aarch64/aarch64-early-ra.cc | 19 ++++++++---- gcc/testsuite/go.dg/pr113636.go | 40 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/go.dg/pr113636.go diff --git a/gcc/config/aarch64/aarch64-early-ra.cc b/gcc/config/aarch64/aarch64-early-ra.cc index 033eac7aaf1..028296639b8 100644 --- a/gcc/config/aarch64/aarch64-early-ra.cc +++ b/gcc/config/aarch64/aarch64-early-ra.cc @@ -478,7 +478,7 @@ private: void broaden_colors (); void finalize_allocation (); - bool replace_regs (df_ref); + bool replace_regs (rtx_insn *, df_ref); int try_enforce_constraints (rtx_insn *, vec> &); void enforce_constraints (rtx_insn *); bool maybe_convert_to_strided_access (rtx_insn *); @@ -2981,8 +2981,9 @@ early_ra::finalize_allocation () } // Replace any allocno references in REFS with the allocated register. +// INSN is the instruction that contains REFS. bool -early_ra::replace_regs (df_ref refs) +early_ra::replace_regs (rtx_insn *insn, df_ref refs) { bool changed = false; for (df_ref ref = refs; ref; ref = DF_REF_NEXT_LOC (ref)) @@ -2992,6 +2993,14 @@ early_ra::replace_regs (df_ref refs) continue; auto new_regno = range.allocno (0)->hard_regno; + if (new_regno == FIRST_PSEUDO_REGISTER) + { + // Reset a debug instruction if, after DCE, the only remaining + // references to a register are in such instructions. + gcc_assert (DEBUG_INSN_P (insn)); + INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); + return true; + } *DF_REF_LOC (ref) = gen_rtx_REG (GET_MODE (DF_REF_REG (ref)), new_regno); changed = true; } @@ -3224,8 +3233,8 @@ early_ra::apply_allocation () continue; bool changed = maybe_convert_to_strided_access (insn); - changed |= replace_regs (DF_INSN_DEFS (insn)); - changed |= replace_regs (DF_INSN_USES (insn)); + changed |= replace_regs (insn, DF_INSN_DEFS (insn)); + changed |= replace_regs (insn, DF_INSN_USES (insn)); if (changed && NONDEBUG_INSN_P (insn)) { if (GET_CODE (PATTERN (insn)) != USE @@ -3245,7 +3254,7 @@ early_ra::apply_allocation () else ptr = &XEXP (*ptr, 1); } - changed |= replace_regs (DF_INSN_EQ_USES (insn)); + changed |= replace_regs (insn, DF_INSN_EQ_USES (insn)); if (changed) df_insn_rescan (insn); } diff --git a/gcc/testsuite/go.dg/pr113636.go b/gcc/testsuite/go.dg/pr113636.go new file mode 100644 index 00000000000..3f43b696765 --- /dev/null +++ b/gcc/testsuite/go.dg/pr113636.go @@ -0,0 +1,40 @@ +// { dg-do compile } +// { dg-options "-O3 -g" } +// { dg-additional-options "-mtune=thunderxt88" { target aarch64*-*-* } } + +package main + +import "math" + +func sinhcosh(x float64) (sh, ch float64) { + if math.Abs(x) <= 0.5 { + return math.Sinh(x), math.Cosh(x) + } + e := math.Exp(x) + ei := 0.5 / e + e *= 0.5 + return e - ei, e + ei +} + +func Cos(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)): + return complex(math.NaN(), -im*math.Copysign(0, re)) + case math.IsInf(im, 0): + switch { + // case re == 0: + // return complex(math.Inf(1), -re*math.Copysign(0, im)) + case math.IsInf(re, 0) || math.IsNaN(re): + return complex(math.Inf(1), math.NaN()) + } + // case re == 0 && math.IsNaN(im): + // return complex(math.NaN(), 0) + } + s, c := math.Sincos(real(x)) + sh, ch := sinhcosh(imag(x)) + return complex(c*ch, -s*sh) +} + +func main() { + Cos(complex(2.5, 3.5)) +}