Skip to content

Commit 8664637

Browse files
sdesmalen-armwwwatermiao
authored andcommitted
[AArch64] Replace LLVM IR function attributes for PSTATE.ZA. (#79166)
Since ARM-software/acle#276 the ACLE defines attributes to better describe the use of a given SME state. Previously the attributes merely described the possibility of it being 'shared' or 'preserved', whereas the new attributes have more semantics and also describe how the data flows through the program. For ZT0 we already had to add new LLVM IR attributes: * aarch64_new_zt0 * aarch64_in_zt0 * aarch64_out_zt0 * aarch64_inout_zt0 * aarch64_preserves_zt0 We have now done the same for ZA, such that we add: * aarch64_new_za (previously `aarch64_pstate_za_new`) * aarch64_in_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_out_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_inout_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_preserves_za (previously `aarch64_pstate_za_shared, aarch64_pstate_za_preserved`) This explicitly removes 'pstate' from the name, because with SME2 and the new ACLE attributes there is a difference between "sharing ZA" (sharing the ZA matrix register with the caller) and "sharing PSTATE.ZA" (sharing either the ZA or ZT0 register, both part of PSTATE.ZA with the caller). Signed-off-by: chenmiao <[email protected]> Signed-off-by: chenmiao <[email protected]>
1 parent f89586e commit 8664637

20 files changed

+287
-152
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10068,10 +10068,8 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
1006810068
llvm::FunctionType::get(StructType::get(CGM.Int64Ty, CGM.Int64Ty), {},
1006910069
false),
1007010070
"__arm_sme_state"));
10071-
auto Attrs =
10072-
AttributeList()
10073-
.addFnAttribute(getLLVMContext(), "aarch64_pstate_sm_compatible")
10074-
.addFnAttribute(getLLVMContext(), "aarch64_pstate_za_preserved");
10071+
auto Attrs = AttributeList().addFnAttribute(getLLVMContext(),
10072+
"aarch64_pstate_sm_compatible");
1007510073
CI->setAttributes(Attrs);
1007610074
CI->setCallingConv(
1007710075
llvm::CallingConv::

clang/lib/CodeGen/CGCall.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,14 +1770,14 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
17701770
FuncAttrs.addAttribute("aarch64_pstate_sm_compatible");
17711771

17721772
// ZA
1773-
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out ||
1774-
FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
1775-
FuncAttrs.addAttribute("aarch64_pstate_za_shared");
1776-
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves ||
1777-
FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In) {
1778-
FuncAttrs.addAttribute("aarch64_pstate_za_shared");
1779-
FuncAttrs.addAttribute("aarch64_pstate_za_preserved");
1780-
}
1773+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves)
1774+
FuncAttrs.addAttribute("aarch64_preserves_za");
1775+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In)
1776+
FuncAttrs.addAttribute("aarch64_in_za");
1777+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out)
1778+
FuncAttrs.addAttribute("aarch64_out_za");
1779+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
1780+
FuncAttrs.addAttribute("aarch64_inout_za");
17811781
}
17821782

17831783
static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs,

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2295,7 +2295,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
22952295

22962296
if (auto *Attr = D->getAttr<ArmNewAttr>()) {
22972297
if (Attr->isNewZA())
2298-
B.addAttribute("aarch64_pstate_za_new");
2298+
B.addAttribute("aarch64_new_za");
22992299
}
23002300

23012301
// Track whether we need to add the optnone LLVM attribute,

clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,20 @@ int test_variadic_template() __arm_inout("za") {
284284
// CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
285285
// CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
286286
// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
287-
// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_pstate_za_shared" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
288-
// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_pstate_za_shared" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
289-
// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_pstate_za_preserved" "aarch64_pstate_za_shared" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
290-
// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_pstate_za_preserved" "aarch64_pstate_za_shared" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
291-
// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_pstate_za_new" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
287+
// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
288+
// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
289+
// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
290+
// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
291+
// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_new_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
292292
// CHECK: attributes #[[NORMAL_DEF]] = { mustprogress noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
293293
// CHECK: attributes #[[SM_ENABLED_CALL]] = { "aarch64_pstate_sm_enabled" }
294294
// CHECK: attributes #[[SM_COMPATIBLE_CALL]] = { "aarch64_pstate_sm_compatible" }
295295
// CHECK: attributes #[[SM_BODY_CALL]] = { "aarch64_pstate_sm_body" }
296-
// CHECK: attributes #[[ZA_SHARED_CALL]] = { "aarch64_pstate_za_shared" }
297-
// CHECK: attributes #[[ZA_PRESERVED_CALL]] = { "aarch64_pstate_za_preserved" "aarch64_pstate_za_shared" }
296+
// CHECK: attributes #[[ZA_SHARED_CALL]] = { "aarch64_inout_za" }
297+
// CHECK: attributes #[[ZA_PRESERVED_CALL]] = { "aarch64_preserves_za" }
298298
// CHECK: attributes #[[NOUNWIND_CALL]] = { nounwind }
299299
// CHECK: attributes #[[NOUNWIND_SM_ENABLED_CALL]] = { nounwind "aarch64_pstate_sm_enabled" }
300300
// CHECK: attributes #[[NOUNWIND_SM_COMPATIBLE_CALL]] = { nounwind "aarch64_pstate_sm_compatible" }
301-
// CHECK: attributes #[[NOUNWIND_ZA_SHARED_CALL]] = { nounwind "aarch64_pstate_za_shared" }
302-
// CHECK: attributes #[[NOUNWIND_ZA_PRESERVED_CALL]] = { nounwind "aarch64_pstate_za_preserved" "aarch64_pstate_za_shared" }
301+
// CHECK: attributes #[[NOUNWIND_ZA_SHARED_CALL]] = { nounwind "aarch64_inout_za" }
302+
// CHECK: attributes #[[NOUNWIND_ZA_PRESERVED_CALL]] = { nounwind "aarch64_preserves_za" }
303303

clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@ void test_svzero_mask_za_2(void) __arm_inout("za") {
3535
svzero_mask_za(255);
3636
}
3737

38-
// CHECK-C-LABEL: @test_svzero_za(
39-
// CHECK-CXX-LABEL: @_Z14test_svzero_zav(
40-
// CHECK-NEXT: entry:
41-
// CHECK-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255)
42-
// CHECK-NEXT: ret void
38+
// CHECK-C-LABEL: define dso_local void @test_svzero_za(
39+
// CHECK-C-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] {
40+
// CHECK-C-NEXT: entry:
41+
// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255)
42+
// CHECK-C-NEXT: ret void
43+
//
44+
// CHECK-CXX-LABEL: define dso_local void @_Z14test_svzero_zav(
45+
// CHECK-CXX-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] {
46+
// CHECK-CXX-NEXT: entry:
47+
// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255)
48+
// CHECK-CXX-NEXT: ret void
4349
//
4450
void test_svzero_za(void) __arm_out("za") {
4551
svzero_za();

clang/test/Modules/aarch64-sme-keywords.cppm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ import A;
4343
//
4444
// CHECK:declare void @_ZW1A22f_streaming_compatiblev() #[[STREAMING_COMPATIBLE_DECL:[0-9]+]]
4545
//
46-
// CHECK-DAG: attributes #[[SHARED_ZA_DEF]] = {{{.*}} "aarch64_pstate_za_shared" {{.*}}}
47-
// CHECK-DAG: attributes #[[SHARED_ZA_DECL]] = {{{.*}} "aarch64_pstate_za_shared" {{.*}}}
48-
// CHECK-DAG: attributes #[[PRESERVES_ZA_DECL]] = {{{.*}} "aarch64_pstate_za_preserved" {{.*}}}
46+
// CHECK-DAG: attributes #[[SHARED_ZA_DEF]] = {{{.*}} "aarch64_inout_za" {{.*}}}
47+
// CHECK-DAG: attributes #[[SHARED_ZA_DECL]] = {{{.*}} "aarch64_inout_za" {{.*}}}
48+
// CHECK-DAG: attributes #[[PRESERVES_ZA_DECL]] = {{{.*}} "aarch64_preserves_za" {{.*}}}
4949
// CHECK-DAG: attributes #[[NORMAL_DEF]] = {{{.*}}}
5050
// CHECK-DAG: attributes #[[STREAMING_DECL]] = {{{.*}} "aarch64_pstate_sm_enabled" {{.*}}}
5151
// CHECK-DAG: attributes #[[STREAMING_COMPATIBLE_DECL]] = {{{.*}} "aarch64_pstate_sm_compatible" {{.*}}}
52-
// CHECK-DAG: attributes #[[SHARED_ZA_USE]] = { "aarch64_pstate_za_shared" }
53-
// CHECK-DAG: attributes #[[PRESERVES_ZA_USE]] = { "aarch64_pstate_za_preserved" "aarch64_pstate_za_shared" }
52+
// CHECK-DAG: attributes #[[SHARED_ZA_USE]] = { "aarch64_inout_za" }
53+
// CHECK-DAG: attributes #[[PRESERVES_ZA_USE]] = { "aarch64_preserves_za" }
5454
// CHECK-DAG: attributes #[[STREAMING_USE]] = { "aarch64_pstate_sm_enabled" }
5555
// CHECK-DAG: attributes #[[STREAMING_COMPATIBLE_USE]] = { "aarch64_pstate_sm_compatible" }
5656

llvm/docs/AArch64SME.rst

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,32 @@ Below we describe the LLVM IR attributes and their relation to the C/C++
2222
level ACLE attributes:
2323

2424
``aarch64_pstate_sm_enabled``
25-
is used for functions with ``__attribute__((arm_streaming))``
25+
is used for functions with ``__arm_streaming``
2626

2727
``aarch64_pstate_sm_compatible``
28-
is used for functions with ``__attribute__((arm_streaming_compatible))``
28+
is used for functions with ``__arm_streaming_compatible``
2929

3030
``aarch64_pstate_sm_body``
31-
is used for functions with ``__attribute__((arm_locally_streaming))`` and is
31+
is used for functions with ``__arm_locally_streaming`` and is
3232
only valid on function definitions (not declarations)
3333

34-
``aarch64_pstate_za_new``
35-
is used for functions with ``__attribute__((arm_new_za))``
34+
``aarch64_new_za``
35+
is used for functions with ``__arm_new("za")``
3636

37-
``aarch64_pstate_za_shared``
38-
is used for functions with ``__attribute__((arm_shared_za))``
37+
``aarch64_in_za``
38+
is used for functions with ``__arm_in("za")``
3939

40-
``aarch64_pstate_za_preserved``
41-
is used for functions with ``__attribute__((arm_preserves_za))``
40+
``aarch64_out_za``
41+
is used for functions with ``__arm_out("za")``
42+
43+
``aarch64_inout_za``
44+
is used for functions with ``__arm_inout("za")``
45+
46+
``aarch64_preserves_za``
47+
is used for functions with ``__arm_preserves("za")``
4248

4349
``aarch64_expanded_pstate_za``
44-
is used for functions with ``__attribute__((arm_new_za))``
50+
is used for functions with ``__arm_new_za``
4551

4652
Clang must ensure that the above attributes are added both to the
4753
function's declaration/definition as well as to their call-sites. This is
@@ -89,11 +95,10 @@ Restrictions on attributes
8995
* It is not allowed for a function to be decorated with both
9096
``aarch64_pstate_sm_compatible`` and ``aarch64_pstate_sm_enabled``.
9197

92-
* It is not allowed for a function to be decorated with both
93-
``aarch64_pstate_za_new`` and ``aarch64_pstate_za_preserved``.
94-
95-
* It is not allowed for a function to be decorated with both
96-
``aarch64_pstate_za_new`` and ``aarch64_pstate_za_shared``.
98+
* It is not allowed for a function to be decorated with more than one of the
99+
following attributes:
100+
``aarch64_new_za``, ``aarch64_in_za``, ``aarch64_out_za``, ``aarch64_inout_za``,
101+
``aarch64_preserves_za``.
97102

98103
These restrictions also apply in the higher level SME ACLE, which means we can
99104
emit diagnostics in Clang to signal users about incorrect behaviour.
@@ -426,7 +431,7 @@ to toggle PSTATE.ZA using intrinsics. This also makes it simpler to setup a
426431
lazy-save mechanism for calls to private-ZA functions (i.e. functions that may
427432
either directly or indirectly clobber ZA state).
428433

429-
For the purpose of handling functions marked with ``aarch64_pstate_za_new``,
434+
For the purpose of handling functions marked with ``aarch64_new_za``,
430435
we have introduced a new LLVM IR pass (SMEABIPass) that is run just before
431436
SelectionDAG. Any such functions dealt with by this pass are marked with
432437
``aarch64_expanded_pstate_za``.

llvm/lib/IR/Verifier.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,17 +2116,13 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
21162116
V);
21172117
}
21182118

2119-
if (Attrs.hasFnAttr("aarch64_pstate_za_new")) {
2120-
Check(!Attrs.hasFnAttr("aarch64_pstate_za_preserved"),
2121-
"Attributes 'aarch64_pstate_za_new and aarch64_pstate_za_preserved' "
2122-
"are incompatible!",
2123-
V);
2124-
2125-
Check(!Attrs.hasFnAttr("aarch64_pstate_za_shared"),
2126-
"Attributes 'aarch64_pstate_za_new and aarch64_pstate_za_shared' "
2127-
"are incompatible!",
2128-
V);
2129-
}
2119+
Check((Attrs.hasFnAttr("aarch64_new_za") + Attrs.hasFnAttr("aarch64_in_za") +
2120+
Attrs.hasFnAttr("aarch64_inout_za") +
2121+
Attrs.hasFnAttr("aarch64_out_za") +
2122+
Attrs.hasFnAttr("aarch64_preserves_za")) <= 1,
2123+
"Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
2124+
"'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive",
2125+
V);
21302126

21312127
if (Attrs.hasFnAttr(Attribute::JumpTable)) {
21322128
const GlobalValue *GV = cast<GlobalValue>(V);

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
230230
CalleeAttrs.set(SMEAttrs::SM_Enabled, true);
231231
}
232232

233-
if (CalleeAttrs.hasNewZABody())
233+
if (CalleeAttrs.isNewZA())
234234
return false;
235235

236236
if (CallerAttrs.requiresLazySave(CalleeAttrs) ||

llvm/lib/Target/AArch64/SMEABIPass.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,8 @@ FunctionPass *llvm::createSMEABIPass() { return new SMEABI(); }
6161
void emitTPIDR2Save(Module *M, IRBuilder<> &Builder) {
6262
auto *TPIDR2SaveTy =
6363
FunctionType::get(Builder.getVoidTy(), {}, /*IsVarArgs=*/false);
64-
auto Attrs =
65-
AttributeList()
66-
.addFnAttribute(M->getContext(), "aarch64_pstate_sm_compatible")
67-
.addFnAttribute(M->getContext(), "aarch64_pstate_za_preserved");
64+
auto Attrs = AttributeList().addFnAttribute(M->getContext(),
65+
"aarch64_pstate_sm_compatible");
6866
FunctionCallee Callee =
6967
M->getOrInsertFunction("__arm_tpidr2_save", TPIDR2SaveTy, Attrs);
7068
CallInst *Call = Builder.CreateCall(Callee);
@@ -79,7 +77,7 @@ void emitTPIDR2Save(Module *M, IRBuilder<> &Builder) {
7977
}
8078

8179
/// This function generates code at the beginning and end of a function marked
82-
/// with either `aarch64_pstate_za_new` or `aarch64_new_zt0`.
80+
/// with either `aarch64_new_za` or `aarch64_new_zt0`.
8381
/// At the beginning of the function, the following code is generated:
8482
/// - Commit lazy-save if active [Private-ZA Interface*]
8583
/// - Enable PSTATE.ZA [Private-ZA Interface]
@@ -134,7 +132,7 @@ bool SMEABI::updateNewStateFunctions(Module *M, Function *F,
134132
Builder.CreateCall(EnableZAIntr->getFunctionType(), EnableZAIntr);
135133
}
136134

137-
if (FnAttrs.hasNewZABody()) {
135+
if (FnAttrs.isNewZA()) {
138136
Function *ZeroIntr =
139137
Intrinsic::getDeclaration(M, Intrinsic::aarch64_sme_zero);
140138
Builder.CreateCall(ZeroIntr->getFunctionType(), ZeroIntr,
@@ -175,7 +173,7 @@ bool SMEABI::runOnFunction(Function &F) {
175173

176174
bool Changed = false;
177175
SMEAttrs FnAttrs(F);
178-
if (FnAttrs.hasNewZABody() || FnAttrs.isNewZT0())
176+
if (FnAttrs.isNewZA() || FnAttrs.isNewZT0())
179177
Changed |= updateNewStateFunctions(M, &F, Builder, FnAttrs);
180178

181179
return Changed;

llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ void SMEAttrs::set(unsigned M, bool Enable) {
2020

2121
assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) &&
2222
"SM_Enabled and SM_Compatible are mutually exclusive");
23-
assert(!(hasNewZABody() && hasSharedZAInterface()) &&
24-
"ZA_New and ZA_Shared are mutually exclusive");
25-
assert(!(hasNewZABody() && preservesZA()) &&
26-
"ZA_New and ZA_Preserved are mutually exclusive");
27-
assert(!(hasNewZABody() && (Bitmask & SME_ABI_Routine)) &&
23+
24+
// ZA Attrs
25+
assert(!(isNewZA() && (Bitmask & SME_ABI_Routine)) &&
2826
"ZA_New and SME_ABI_Routine are mutually exclusive");
27+
28+
assert(
29+
(!sharesZA() ||
30+
(isNewZA() ^ isInZA() ^ isInOutZA() ^ isOutZA() ^ isPreservesZA())) &&
31+
"Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
32+
"'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive");
2933
}
3034

3135
SMEAttrs::SMEAttrs(const CallBase &CB) {
@@ -39,8 +43,8 @@ SMEAttrs::SMEAttrs(StringRef FuncName) : Bitmask(0) {
3943
if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
4044
Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
4145
if (FuncName == "__arm_tpidr2_restore")
42-
Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::ZA_Shared |
43-
SMEAttrs::SME_ABI_Routine);
46+
Bitmask |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |
47+
SMEAttrs::SME_ABI_Routine;
4448
}
4549

4650
SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
@@ -51,12 +55,16 @@ SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
5155
Bitmask |= SM_Compatible;
5256
if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
5357
Bitmask |= SM_Body;
54-
if (Attrs.hasFnAttr("aarch64_pstate_za_shared"))
55-
Bitmask |= ZA_Shared;
56-
if (Attrs.hasFnAttr("aarch64_pstate_za_new"))
57-
Bitmask |= ZA_New;
58-
if (Attrs.hasFnAttr("aarch64_pstate_za_preserved"))
59-
Bitmask |= ZA_Preserved;
58+
if (Attrs.hasFnAttr("aarch64_in_za"))
59+
Bitmask |= encodeZAState(StateValue::In);
60+
if (Attrs.hasFnAttr("aarch64_out_za"))
61+
Bitmask |= encodeZAState(StateValue::Out);
62+
if (Attrs.hasFnAttr("aarch64_inout_za"))
63+
Bitmask |= encodeZAState(StateValue::InOut);
64+
if (Attrs.hasFnAttr("aarch64_preserves_za"))
65+
Bitmask |= encodeZAState(StateValue::Preserved);
66+
if (Attrs.hasFnAttr("aarch64_new_za"))
67+
Bitmask |= encodeZAState(StateValue::New);
6068
}
6169

6270
bool SMEAttrs::requiresSMChange(const SMEAttrs &Callee) const {

llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.h

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,24 @@ class SMEAttrs {
2626
unsigned Bitmask;
2727

2828
public:
29+
enum class StateValue {
30+
None = 0,
31+
In = 1, //aarch64_in_zt0
32+
Out = 2, //aarch64_out_zt0
33+
InOut = 3, //aarch64_inout_zt0
34+
Preserved = 4, //aarch64_preserves_zt0
35+
New = 5 //aarch64_new_zt0
36+
};
37+
2938
// Enum with bitmasks for each individual SME feature.
3039
enum Mask {
3140
Normal = 0,
3241
SM_Enabled = 1 << 0, // aarch64_pstate_sm_enabled
3342
SM_Compatible = 1 << 1, // aarch64_pstate_sm_compatible
3443
SM_Body = 1 << 2, // aarch64_pstate_sm_body
35-
ZA_Shared = 1 << 3, // aarch64_pstate_sm_shared
36-
ZA_New = 1 << 4, // aarch64_pstate_sm_new
37-
ZA_Preserved = 1 << 5, // aarch64_pstate_sm_preserved
38-
SME_ABI_Routine = 1 << 6, // Used for SME ABI routines to avoid lazy saves
44+
SME_ABI_Routine = 1 << 3, // Used for SME ABI routines to avoid lazy saves
45+
ZA_Shift = 4,
46+
ZA_Mask = 0b111 << ZA_Shift,
3947
};
4048

4149
SMEAttrs(unsigned Mask = Normal) : Bitmask(0) { set(Mask); }
@@ -66,14 +74,29 @@ class SMEAttrs {
6674
/// streaming mode.
6775
bool requiresSMChange(const SMEAttrs &Callee) const;
6876

69-
// Interfaces to query PSTATE.ZA
70-
bool hasNewZABody() const { return Bitmask & ZA_New; }
71-
bool hasSharedZAInterface() const { return Bitmask & ZA_Shared; }
72-
bool hasPrivateZAInterface() const { return !hasSharedZAInterface(); }
73-
bool preservesZA() const { return Bitmask & ZA_Preserved; }
74-
bool hasZAState() const {
75-
return hasNewZABody() || hasSharedZAInterface();
77+
// Interfaces to query ZA
78+
static StateValue decodeZAState(unsigned Bitmask) {
79+
return static_cast<StateValue>((Bitmask & ZA_Mask) >> ZA_Shift);
80+
}
81+
static unsigned encodeZAState(StateValue S) {
82+
return static_cast<unsigned>(S) << ZA_Shift;
7683
}
84+
85+
bool isNewZA() const { return decodeZAState(Bitmask) == StateValue::New; }
86+
bool isInZA() const { return decodeZAState(Bitmask) == StateValue::In; }
87+
bool isOutZA() const { return decodeZAState(Bitmask) == StateValue::Out; }
88+
bool isInOutZA() const { return decodeZAState(Bitmask) == StateValue::InOut; }
89+
bool isPreservesZA() const {
90+
return decodeZAState(Bitmask) == StateValue::Preserved;
91+
}
92+
bool sharesZA() const {
93+
StateValue State = decodeZAState(Bitmask);
94+
return State == StateValue::In || State == StateValue::Out ||
95+
State == StateValue::InOut || State == StateValue::Preserved;
96+
}
97+
bool hasSharedZAInterface() const { return sharesZA() || sharesZT0(); }
98+
bool hasPrivateZAInterface() const { return !hasSharedZAInterface(); }
99+
bool hasZAState() const { return isNewZA() || sharesZA(); }
77100
bool requiresLazySave(const SMEAttrs &Callee) const {
78101
return hasZAState() && Callee.hasPrivateZAInterface() &&
79102
!(Callee.Bitmask & SME_ABI_Routine);

0 commit comments

Comments
 (0)