368 lines
15 KiB
Diff
368 lines
15 KiB
Diff
From 961bde1640e5edb40943b98a1579f67e961bd5ad Mon Sep 17 00:00:00 2001
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
|
Date: Tue, 5 Dec 2023 10:11:21 +0000
|
|
Subject: [PATCH 065/144] aarch64: Make more use of sve_type in ACLE code
|
|
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1f7f076ad6293cad19d35efdf726eb48cf78e3dd
|
|
|
|
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 40aa418e0..f187b4cb2 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 1545fd78d..e98274f8a 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 f7d6cc084..a7cfff7c1 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);
|
|
|
|
--
|
|
2.19.1
|
|
|