1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
From 3d721b42c97baba562b77988cec0fec229217519 Mon Sep 17 00:00:00 2001
From: Richard Sandiford <richard.sandiford@arm.com>
Date: Tue, 5 Dec 2023 10:11:28 +0000
Subject: [PATCH 111/157] [Backport][SME] aarch64: Generalise _m rules for SVE
intrinsics
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8de9304d94d4ec42863a25c1cb1a1ba9a1e3e0fe
In SVE there was a simple rule that unary merging (_m) intrinsics
had a separate initial argument to specify the values of inactive
lanes, whereas other merging functions took inactive lanes from
the first operand to the operation.
That rule began to break down in SVE2, and it continues to do
so in SME. This patch therefore adds a virtual function to
specify whether the separate initial argument is present or not.
The old rule is still the default.
gcc/
* config/aarch64/aarch64-sve-builtins.h
(function_shape::has_merge_argument_p): New member function.
* config/aarch64/aarch64-sve-builtins.cc:
(function_resolver::check_gp_argument): Use it.
(function_expander::get_fallback_value): Likewise.
* config/aarch64/aarch64-sve-builtins-shapes.cc
(apply_predication): Likewise.
(unary_convert_narrowt_def::has_merge_argument_p): New function.
---
gcc/config/aarch64/aarch64-sve-builtins-shapes.cc | 10 ++++++++--
gcc/config/aarch64/aarch64-sve-builtins.cc | 4 ++--
gcc/config/aarch64/aarch64-sve-builtins.h | 13 +++++++++++++
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
index 95e40d8f3..c536949ba 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
@@ -66,8 +66,8 @@ apply_predication (const function_instance &instance, tree return_type,
the same type as the result. For unary_convert_narrowt it also
provides the "bottom" half of active elements, and is present
for all types of predication. */
- if ((argument_types.length () == 2 && instance.pred == PRED_m)
- || instance.shape == shapes::unary_convert_narrowt)
+ auto nargs = argument_types.length () - 1;
+ if (instance.shape->has_merge_argument_p (instance, nargs))
argument_types.quick_insert (0, return_type);
}
}
@@ -3271,6 +3271,12 @@ SHAPE (unary_convert)
predicate. */
struct unary_convert_narrowt_def : public overloaded_base<1>
{
+ bool
+ has_merge_argument_p (const function_instance &, unsigned int) const override
+ {
+ return true;
+ }
+
void
build (function_builder &b, const function_group_info &group) const OVERRIDE
{
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index 5f3a2baea..3441b4294 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -2287,7 +2287,7 @@ function_resolver::check_gp_argument (unsigned int nops,
if (pred != PRED_none)
{
/* Unary merge operations should use resolve_unary instead. */
- gcc_assert (nops != 1 || pred != PRED_m);
+ gcc_assert (!shape->has_merge_argument_p (*this, nops));
nargs = nops + 1;
if (!check_num_arguments (nargs)
|| !require_vector_type (i, VECTOR_TYPE_svbool_t))
@@ -2931,7 +2931,7 @@ function_expander::get_fallback_value (machine_mode mode, unsigned int nops,
gcc_assert (pred == PRED_m || pred == PRED_x);
if (merge_argno == DEFAULT_MERGE_ARGNO)
- merge_argno = nops == 1 && pred == PRED_m ? 0 : 1;
+ merge_argno = shape->has_merge_argument_p (*this, nops) ? 0 : 1;
if (merge_argno == 0)
return args[argno++];
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index 7132b6e77..f16ac3947 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -710,6 +710,9 @@ public:
class function_shape
{
public:
+ virtual bool has_merge_argument_p (const function_instance &,
+ unsigned int) const;
+
virtual bool explicit_type_suffix_p (unsigned int) const = 0;
/* True if the group suffix is present in overloaded names.
@@ -982,6 +985,16 @@ function_base::vectors_per_tuple (const function_instance &instance) const
return instance.group_suffix ().vectors_per_tuple;
}
+/* Return true if INSTANCE (which has NARGS arguments) has an initial
+ vector argument whose only purpose is to specify the values of
+ inactive lanes. */
+inline bool
+function_shape::has_merge_argument_p (const function_instance &instance,
+ unsigned int nargs) const
+{
+ return nargs == 1 && instance.pred == PRED_m;
+}
+
/* Return the mode of the result of a call. */
inline machine_mode
function_expander::result_mode () const
--
2.33.0
|