From patchwork Tue Dec 5 10:13:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1872030 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 4SkxH85Xcxz23mf for ; Tue, 5 Dec 2023 21:15:00 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 47A3C384CB9C for ; Tue, 5 Dec 2023 10:14:49 +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 52B23385DC19 for ; Tue, 5 Dec 2023 10:13:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 52B23385DC19 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 52B23385DC19 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=1701771222; cv=none; b=aewXZYbb06tWcpJg2V0ap+kitCuAi8H+LyhHpJC9lVT0j/+5BFSfE9B7YHWLseguF4z8y4n49fY5C1bTMbSNw7aO1t6jwlD0TWMQJpXsbOiV03mTAyHwrfi1mKTB5QgpSI/WrOrn3uG/A1Fa/uBcuTtumQWwBDxJt2IElWGZDxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701771222; c=relaxed/simple; bh=RAO+z2OFtNddeRCjCNG5irgwPfx4dWi7dR0VqN8C2Go=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=ZPvYMm+InMuZXZfOGqXa/8I7ePKKKPSvJC+Z7XsW+idvQEt5kqwtbkpZKKghe/Zavuw5KTOtn7wQKNcU1mnZVm7PZzMeP37z4Ojk21xDHROIBmaHKACA9E4/BCYq9986bxCmnLv/oEzy5k+fSPcR3GrD4dU8H2K1r9hXWr7Ngqo= 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 B5D3D1476; Tue, 5 Dec 2023 02:14:25 -0800 (PST) Received: from e121540-lin.manchester.arm.com (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A75303F5A1; Tue, 5 Dec 2023 02:13:38 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Cc: Richard Sandiford Subject: [pushed v2 08/25] aarch64: Make more use of sve_type in ACLE code Date: Tue, 5 Dec 2023 10:13:06 +0000 Message-Id: <20231205101323.1914247-9-richard.sandiford@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231205101323.1914247-1-richard.sandiford@arm.com> References: <20231205101323.1914247-1-richard.sandiford@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-22.4 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 This patch makes some functions operate on sve_type, rather than just on type suffixes. It also allows an overload to be resolved based on a mode and sve_type. In this case the sve_type is used to derive the group size as well as a type suffix. This is needed for the SME2 intrinsics and the new tuple forms of svreinterpret. No functional change intended on its own. gcc/ * config/aarch64/aarch64-sve-builtins.h (function_resolver::lookup_form): Add an overload that takes an sve_type rather than type and group suffixes. (function_resolver::resolve_to): Likewise. (function_resolver::infer_vector_or_tuple_type): Return an sve_type. (function_resolver::infer_tuple_type): Likewise. (function_resolver::require_matching_vector_type): Take an sve_type rather than a type_suffix_index. (function_resolver::require_derived_vector_type): Likewise. * config/aarch64/aarch64-sve-builtins.cc (num_vectors_to_group): New function. (function_resolver::lookup_form): Add an overload that takes an sve_type rather than type and group suffixes. (function_resolver::resolve_to): Likewise. (function_resolver::infer_vector_or_tuple_type): Return an sve_type. (function_resolver::infer_tuple_type): Likewise. (function_resolver::infer_vector_type): Update accordingly. (function_resolver::require_matching_vector_type): Take an sve_type rather than a type_suffix_index. (function_resolver::require_derived_vector_type): Likewise. * config/aarch64/aarch64-sve-builtins-shapes.cc (get_def::resolve) (set_def::resolve, store_def::resolve, tbl_tuple_def::resolve): Update calls accordingly. --- .../aarch64/aarch64-sve-builtins-shapes.cc | 16 +-- gcc/config/aarch64/aarch64-sve-builtins.cc | 111 +++++++++++++----- gcc/config/aarch64/aarch64-sve-builtins.h | 12 +- 3 files changed, 95 insertions(+), 44 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc index 7ab94a9cb31..86ec29a5caf 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc @@ -1904,9 +1904,9 @@ struct get_def : public overloaded_base<0> resolve (function_resolver &r) const override { unsigned int i, nargs; - type_suffix_index type; + sve_type type; if (!r.check_gp_argument (2, i, nargs) - || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES + || !(type = r.infer_tuple_type (i)) || !r.require_integer_immediate (i + 1)) return error_mark_node; @@ -2417,9 +2417,9 @@ struct set_def : public overloaded_base<0> resolve (function_resolver &r) const override { unsigned int i, nargs; - type_suffix_index type; + sve_type type; if (!r.check_gp_argument (3, i, nargs) - || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES + || !(type = r.infer_tuple_type (i)) || !r.require_integer_immediate (i + 1) || !r.require_derived_vector_type (i + 2, i, type)) return error_mark_node; @@ -2592,11 +2592,11 @@ struct store_def : public overloaded_base<0> gcc_assert (r.mode_suffix_id == MODE_none || vnum_p); unsigned int i, nargs; - type_suffix_index type; + sve_type type; if (!r.check_gp_argument (vnum_p ? 3 : 2, i, nargs) || !r.require_pointer_type (i) || (vnum_p && !r.require_scalar_type (i + 1, "int64_t")) - || ((type = r.infer_tuple_type (nargs - 1)) == NUM_TYPE_SUFFIXES)) + || !(type = r.infer_tuple_type (nargs - 1))) return error_mark_node; return r.resolve_to (r.mode_suffix_id, type); @@ -2713,9 +2713,9 @@ struct tbl_tuple_def : public overloaded_base<0> resolve (function_resolver &r) const override { unsigned int i, nargs; - type_suffix_index type; + sve_type type; if (!r.check_gp_argument (2, i, nargs) - || (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES + || !(type = r.infer_tuple_type (i)) || !r.require_derived_vector_type (i + 1, i, type, TYPE_unsigned)) return error_mark_node; diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 4203ff4fc41..cdae77272ab 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -659,6 +659,21 @@ find_type_suffix_for_scalar_type (const_tree type) return NUM_TYPE_SUFFIXES; } +/* Return the implicit group suffix for intrinsics that operate on NVECTORS + vectors. */ +static group_suffix_index +num_vectors_to_group (unsigned int nvectors) +{ + switch (nvectors) + { + case 1: return GROUP_none; + case 2: return GROUP_x2; + case 3: return GROUP_x3; + case 4: return GROUP_x4; + } + gcc_unreachable (); +} + /* Return the vector type associated with TYPE. */ static tree get_vector_type (sve_type type) @@ -1282,6 +1297,27 @@ function_resolver::lookup_form (mode_suffix_index mode, return rfn ? rfn->decl : NULL_TREE; } +/* Silently check whether there is an instance of the function that has the + mode suffix given by MODE and the type and group suffixes implied by TYPE. + If the overloaded function has an explicit first type suffix (like + conversions do), TYPE describes the implicit second type suffix. + Otherwise, TYPE describes the only type suffix. + + Return the decl of the function if it exists, otherwise return null. */ +tree +function_resolver::lookup_form (mode_suffix_index mode, sve_type type) +{ + type_suffix_index type0 = type_suffix_ids[0]; + type_suffix_index type1 = type_suffix_ids[1]; + (type0 == NUM_TYPE_SUFFIXES ? type0 : type1) = type.type; + + group_suffix_index group = group_suffix_id; + if (group == GROUP_none && type.num_vectors != vectors_per_tuple ()) + group = num_vectors_to_group (type.num_vectors); + + return lookup_form (mode, type0, type1, group); +} + /* Resolve the function to one with the mode suffix given by MODE, the type suffixes given by TYPE0 and TYPE1, and group suffix given by GROUP. Return its function decl on success, otherwise report an @@ -1305,6 +1341,19 @@ function_resolver::resolve_to (mode_suffix_index mode, return res; } +/* Resolve the function to one that has the suffixes associated with MODE + and TYPE; see lookup_form for how TYPE is interpreted. Return the + function decl on success, otherwise report an error and return + error_mark_node. */ +tree +function_resolver::resolve_to (mode_suffix_index mode, sve_type type) +{ + if (tree res = lookup_form (mode, type)) + return res; + + return report_no_such_form (type); +} + /* Require argument ARGNO to be a 32-bit or 64-bit scalar integer type. Return the associated type suffix on success, otherwise report an error and return NUM_TYPE_SUFFIXES. */ @@ -1424,21 +1473,20 @@ function_resolver::infer_sve_type (unsigned int argno) /* Require argument ARGNO to be a single vector or a tuple of NUM_VECTORS vectors; NUM_VECTORS is 1 for the former. Return the associated type - suffix on success, using TYPE_SUFFIX_b for predicates. Report an error - and return NUM_TYPE_SUFFIXES on failure. */ -type_suffix_index + on success. Report an error on failure. */ +sve_type function_resolver::infer_vector_or_tuple_type (unsigned int argno, unsigned int num_vectors) { auto type = infer_sve_type (argno); if (!type) - return NUM_TYPE_SUFFIXES; + return type; if (type.num_vectors == num_vectors) - return type.type; + return type; report_incorrect_num_vectors (argno, type, num_vectors); - return NUM_TYPE_SUFFIXES; + return {}; } /* Require argument ARGNO to have some form of vector type. Return the @@ -1447,7 +1495,9 @@ function_resolver::infer_vector_or_tuple_type (unsigned int argno, type_suffix_index function_resolver::infer_vector_type (unsigned int argno) { - return infer_vector_or_tuple_type (argno, 1); + if (auto type = infer_vector_or_tuple_type (argno, 1)) + return type.type; + return NUM_TYPE_SUFFIXES; } /* Like infer_vector_type, but also require the type to be integral. */ @@ -1512,10 +1562,9 @@ function_resolver::infer_sd_vector_type (unsigned int argno) /* If the function operates on tuples of vectors, require argument ARGNO to be a tuple with the appropriate number of vectors, otherwise require it to be - a single vector. Return the associated type suffix on success, using - TYPE_SUFFIX_b for predicates. Report an error and return NUM_TYPE_SUFFIXES + a single vector. Return the associated type on success. Report an error on failure. */ -type_suffix_index +sve_type function_resolver::infer_tuple_type (unsigned int argno) { return infer_vector_or_tuple_type (argno, vectors_per_tuple ()); @@ -1567,10 +1616,10 @@ function_resolver::require_vector_type (unsigned int argno, bool function_resolver::require_matching_vector_type (unsigned int argno, unsigned int first_argno, - type_suffix_index type) + sve_type type) { - type_suffix_index new_type = infer_vector_type (argno); - if (new_type == NUM_TYPE_SUFFIXES) + sve_type new_type = infer_sve_type (argno); + if (!new_type) return false; if (type != new_type) @@ -1613,15 +1662,13 @@ function_resolver::require_matching_vector_type (unsigned int argno, bool function_resolver:: require_derived_vector_type (unsigned int argno, unsigned int first_argno, - type_suffix_index first_type, + sve_type first_type, type_class_index expected_tclass, unsigned int expected_bits) { /* If the type needs to match FIRST_ARGNO exactly, use the preferred - error message for that case. The VECTOR_TYPE_P test excludes tuple - types, which we handle below instead. */ - bool both_vectors_p = VECTOR_TYPE_P (get_argument_type (first_argno)); - if (both_vectors_p + error message for that case. */ + if (first_type.num_vectors == 1 && expected_tclass == SAME_TYPE_CLASS && expected_bits == SAME_SIZE) { @@ -1631,17 +1678,18 @@ require_derived_vector_type (unsigned int argno, } /* Use FIRST_TYPE to get the expected type class and element size. */ + auto &first_type_suffix = type_suffixes[first_type.type]; type_class_index orig_expected_tclass = expected_tclass; if (expected_tclass == NUM_TYPE_CLASSES) - expected_tclass = type_suffixes[first_type].tclass; + expected_tclass = first_type_suffix.tclass; unsigned int orig_expected_bits = expected_bits; if (expected_bits == SAME_SIZE) - expected_bits = type_suffixes[first_type].element_bits; + expected_bits = first_type_suffix.element_bits; else if (expected_bits == HALF_SIZE) - expected_bits = type_suffixes[first_type].element_bits / 2; + expected_bits = first_type_suffix.element_bits / 2; else if (expected_bits == QUARTER_SIZE) - expected_bits = type_suffixes[first_type].element_bits / 4; + expected_bits = first_type_suffix.element_bits / 4; /* If the expected type doesn't depend on FIRST_TYPE at all, just check for the fixed choice of vector type. */ @@ -1655,13 +1703,14 @@ require_derived_vector_type (unsigned int argno, /* Require the argument to be some form of SVE vector type, without being specific about the type of vector we want. */ - type_suffix_index actual_type = infer_vector_type (argno); - if (actual_type == NUM_TYPE_SUFFIXES) + sve_type actual_type = infer_vector_type (argno); + if (!actual_type) return false; /* Exit now if we got the right type. */ - bool tclass_ok_p = (type_suffixes[actual_type].tclass == expected_tclass); - bool size_ok_p = (type_suffixes[actual_type].element_bits == expected_bits); + auto &actual_type_suffix = type_suffixes[actual_type.type]; + bool tclass_ok_p = (actual_type_suffix.tclass == expected_tclass); + bool size_ok_p = (actual_type_suffix.element_bits == expected_bits); if (tclass_ok_p && size_ok_p) return true; @@ -1701,7 +1750,9 @@ require_derived_vector_type (unsigned int argno, /* If the arguments have consistent type classes, but a link between the sizes has been broken, try to describe the error in those terms. */ - if (both_vectors_p && tclass_ok_p && orig_expected_bits == SAME_SIZE) + if (first_type.num_vectors == 1 + && tclass_ok_p + && orig_expected_bits == SAME_SIZE) { if (argno < first_argno) { @@ -1718,11 +1769,11 @@ require_derived_vector_type (unsigned int argno, /* Likewise in reverse: look for cases in which the sizes are consistent but a link between the type classes has been broken. */ - if (both_vectors_p + if (first_type.num_vectors == 1 && size_ok_p && orig_expected_tclass == SAME_TYPE_CLASS - && type_suffixes[first_type].integer_p - && type_suffixes[actual_type].integer_p) + && first_type_suffix.integer_p + && actual_type_suffix.integer_p) { if (argno < first_argno) { diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index f959b6f6ab3..0b40ad7b7cd 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -458,28 +458,28 @@ public: type_suffix_index = NUM_TYPE_SUFFIXES, type_suffix_index = NUM_TYPE_SUFFIXES, group_suffix_index = GROUP_none); + tree lookup_form (mode_suffix_index, sve_type); tree resolve_to (mode_suffix_index, type_suffix_index = NUM_TYPE_SUFFIXES, type_suffix_index = NUM_TYPE_SUFFIXES, group_suffix_index = GROUP_none); + tree resolve_to (mode_suffix_index, sve_type); type_suffix_index infer_integer_scalar_type (unsigned int); type_suffix_index infer_pointer_type (unsigned int, bool = false); sve_type infer_sve_type (unsigned int); - type_suffix_index infer_vector_or_tuple_type (unsigned int, unsigned int); + sve_type infer_vector_or_tuple_type (unsigned int, unsigned int); type_suffix_index infer_vector_type (unsigned int); type_suffix_index infer_integer_vector_type (unsigned int); type_suffix_index infer_unsigned_vector_type (unsigned int); type_suffix_index infer_sd_vector_type (unsigned int); - type_suffix_index infer_tuple_type (unsigned int); + sve_type infer_tuple_type (unsigned int); bool require_vector_or_scalar_type (unsigned int); bool require_vector_type (unsigned int, vector_type_index); - bool require_matching_vector_type (unsigned int, unsigned int, - type_suffix_index); - bool require_derived_vector_type (unsigned int, unsigned int, - type_suffix_index, + bool require_matching_vector_type (unsigned int, unsigned int, sve_type); + bool require_derived_vector_type (unsigned int, unsigned int, sve_type, type_class_index = SAME_TYPE_CLASS, unsigned int = SAME_SIZE);