From patchwork Tue Jan 7 17:54:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 104288 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B49D93858D21 for ; Tue, 7 Jan 2025 17:54:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B49D93858D21 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 AE14F3858D21 for ; Tue, 7 Jan 2025 17:54:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AE14F3858D21 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 AE14F3858D21 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=1736272442; cv=none; b=ItlXv2VpXZ6yHioewWyP5DwQTQde+uWqDHqt/+K86TShJ/DSMHNj/ok00QxreT1vmuLmf4GvCGp1xp02DtLZR1L2Vh9XSu65/OS5fCv+V/FvcB9FM+ZQ5mjRyqMoP7Ke1hLJnQaB8aN7NnvpU01CDFV9M1CATRDOgjUR2UaUpu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736272442; c=relaxed/simple; bh=j0T6X1YzjfdDJh4A9AgVfK+wxyS0lgd37tK25FF0jpA=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=EMRjQO9ERx9lpiNgdk5rDBRylSUIT1HV5zKy+prBvS9Emnf7pgV6QAQnJOLk/urILAcoXKyhL9+rfSa4uji0RpFmCd9cNtyTnEIMqFng9VBiCeSiAh4ZQdoYuJBkEqsDX0dohZYVWNqGne2W6D2xjni9j6SswoYlhvLDj+0hyMo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AE14F3858D21 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 8D1161424; Tue, 7 Jan 2025 09:54:30 -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 A18F13F673; Tue, 7 Jan 2025 09:54:01 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org,richard.earnshaw@arm.com, ktkachov@nvidia.com, richard.sandiford@arm.com Cc: richard.earnshaw@arm.com, ktkachov@nvidia.com Subject: [PATCH] aarch64: Fix overly restrictive sibcall check [PR107102] Date: Tue, 07 Jan 2025 17:54:00 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, 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~patchwork=sourceware.org@gcc.gnu.org aarch64_function_ok_for_sibcall required the caller and callee to use the same PCS variant. However, it should be enough for the callee to preserve at least as much register state as the caller; preserving more state is fine. ARM_PCS_AAPCS64, ARM_PCS_SIMD, and ARM_PCS_SVE agree on what GPRs should be preserved. For the others: - ARM_PCS_AAPCS64 preserves D8-D15 - ARM_PCS_SIMD preserves Q8-Q23 - ARM_PCS_SVE preserves Z8-Z23 + P4-P15 Thus it's ok for something earlier in the list to tail call something later in the list. Tested on aarch64-linux-gnu. I'll push tomorrow evening UTC if there are no comments before then. Richard gcc/ PR target/107102 * config/aarch64/aarch64.cc (aarch64_function_ok_for_sibcall): Only reject calls with different PCSes if the callee clobbers register state that the caller must preserve. gcc/testsuite/ PR target/107102 * gcc.target/aarch64/sve/sibcall_1.c: New test. --- gcc/config/aarch64/aarch64.cc | 12 ++- .../gcc.target/aarch64/sve/sibcall_1.c | 80 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sibcall_1.c diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 9e69bc74449..fa2f19467e3 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -6591,7 +6591,17 @@ aarch64_split_sve_subreg_move (rtx dest, rtx ptrue, rtx src) static bool aarch64_function_ok_for_sibcall (tree, tree exp) { - if (crtl->abi->id () != expr_callee_abi (exp).id ()) + auto from_abi = crtl->abi->id (); + auto to_abi = expr_callee_abi (exp).id (); + + /* ARM_PCS_SVE preserves strictly more than ARM_PCS_SIMD, which in + turn preserves strictly more than the base PCS. The callee must + preserve everything that the caller is required to preserve. */ + if (from_abi != to_abi && to_abi == ARM_PCS_SVE) + to_abi = ARM_PCS_SIMD; + if (from_abi != to_abi && to_abi == ARM_PCS_SIMD) + to_abi = ARM_PCS_AAPCS64; + if (from_abi != to_abi) return false; tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sibcall_1.c b/gcc/testsuite/gcc.target/aarch64/sve/sibcall_1.c new file mode 100644 index 00000000000..a54c107998e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sibcall_1.c @@ -0,0 +1,80 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +#define SIMD [[gnu::aarch64_vector_pcs]] + +void callee_base (void); +void callee_simd (void) SIMD; +void callee_sve (__SVBool_t); + +/* +** base_to_base: +** b callee_base +*/ +void base_to_base (void) { return callee_base (); } + +/* +** base_to_simd: +** b callee_simd +*/ +void base_to_simd (void) { return callee_simd (); } + +/* +** base_to_sve: +** ldr p0, \[x0\] +** b callee_sve +*/ +void base_to_sve (__SVBool_t *ptr) { return callee_sve (*ptr); } + +/* +** simd_to_base: +** stp x29, x30, [^\n]+ +** ... +** bl callee_base +** ... +** ldp x29, x30, [^\n]+ +** ret +*/ +void simd_to_base (void) SIMD { return callee_base (); } + +/* +** simd_to_simd: +** b callee_simd +*/ +void simd_to_simd (void) SIMD { return callee_simd (); } + +/* +** simd_to_sve: +** ldr p0, \[x0\] +** b callee_sve +*/ +void simd_to_sve (__SVBool_t *ptr) SIMD { return callee_sve (*ptr); } + +/* +** sve_to_base: +** stp x29, x30, [^\n]+ +** ... +** bl callee_base +** ... +** ldp x29, x30, [^\n]+ +** ret +*/ +void sve_to_base (__SVBool_t pg) { return callee_base (); } + +/* +** sve_to_simd: +** stp x29, x30, [^\n]+ +** ... +** bl callee_simd +** ... +** ldp x29, x30, [^\n]+ +** ret +*/ +void sve_to_simd (__SVBool_t pg) { return callee_simd (); } + +/* +** sve_to_sve: +** b callee_sve +*/ +void sve_to_sve (__SVBool_t pg) { return callee_sve (pg); }