Skip to content

Commit 3be3f5f

Browse files
committed
[Clang] Amend SME attributes with support for ZT0.
This patch builds on top of #76971 and implements support for: * __arm_new("zt0") * __arm_in("zt0") * __arm_out("zt0") * __arm_inout("zt0") * __arm_preserves("zt0") The patch is ready for review but won't be able to land until LLVM implements support for handling ZT0 state.
1 parent d24f23e commit 3be3f5f

File tree

13 files changed

+186
-5
lines changed

13 files changed

+186
-5
lines changed

clang/include/clang/AST/Type.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4056,10 +4056,12 @@ class FunctionType : public Type {
40564056
// Describes the value of the state using ArmStateValue.
40574057
SME_ZAShift = 2,
40584058
SME_ZAMask = 0b111 << SME_ZAShift,
4059+
SME_ZT0Shift = 5,
4060+
SME_ZT0Mask = 0b111 << SME_ZT0Shift,
40594061

4060-
SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of
4061-
// the bitmask in FunctionTypeArmAttributes
4062-
// and ExtProtoInfo.
4062+
SME_AttributeMask =
4063+
0b111'111'11 // We can't support more than 8 bits because of
4064+
// the bitmask in FunctionTypeExtraBitfields.
40634065
};
40644066

40654067
enum ArmStateValue : unsigned {
@@ -4074,13 +4076,17 @@ class FunctionType : public Type {
40744076
return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
40754077
}
40764078

4079+
static ArmStateValue getArmZT0State(unsigned AttrBits) {
4080+
return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
4081+
}
4082+
40774083
/// A holder for Arm type attributes as described in the Arm C/C++
40784084
/// Language extensions which are not particularly common to all
40794085
/// types and therefore accounted separately from FunctionTypeBitfields.
40804086
struct alignas(void *) FunctionTypeArmAttributes {
40814087
/// Any AArch64 SME ACLE type attributes that need to be propagated
40824088
/// on declarations and function pointers.
4083-
unsigned AArch64SMEAttributes : 6;
4089+
unsigned AArch64SMEAttributes : 8;
40844090

40854091
FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {}
40864092
};
@@ -4266,7 +4272,7 @@ class FunctionProtoType final
42664272
FunctionType::ExtInfo ExtInfo;
42674273
unsigned Variadic : 1;
42684274
unsigned HasTrailingReturn : 1;
4269-
unsigned AArch64SMEAttributes : 6;
4275+
unsigned AArch64SMEAttributes : 8;
42704276
Qualifiers TypeQuals;
42714277
RefQualifierKind RefQualifier = RQ_None;
42724278
ExceptionSpecInfo ExceptionSpec;

clang/include/clang/Basic/Attr.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2552,6 +2552,9 @@ def ArmNew : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
25522552
bool isNewZA() const {
25532553
return llvm::is_contained(newArgs(), "za");
25542554
}
2555+
bool isNewZT0() const {
2556+
return llvm::is_contained(newArgs(), "zt0");
2557+
}
25552558
}];
25562559
}
25572560

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3698,10 +3698,14 @@ def err_sme_call_in_non_sme_target : Error<
36983698
"call to a streaming function requires 'sme'">;
36993699
def err_sme_za_call_no_za_state : Error<
37003700
"call to a shared ZA function requires the caller to have ZA state">;
3701+
def err_sme_zt0_call_no_zt0_state : Error<
3702+
"call to a shared ZT0 function requires the caller to have ZT0 state">;
37013703
def err_sme_definition_using_sm_in_non_sme_target : Error<
37023704
"function executed in streaming-SVE mode requires 'sme'">;
37033705
def err_sme_definition_using_za_in_non_sme_target : Error<
37043706
"function using ZA state requires 'sme'">;
3707+
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
3708+
"function using ZT0 state requires 'sme2'">;
37053709
def err_conflicting_attributes_arm_state : Error<
37063710
"conflicting attributes for state '%0'">;
37073711
def err_unknown_arm_state : Error<

clang/lib/AST/TypePrinter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,14 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
951951
OS << " __arm_out(\"za\")";
952952
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
953953
OS << " __arm_inout(\"za\")";
954+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
955+
OS << " __arm_preserves(\"zt0\")";
956+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
957+
OS << " __arm_in(\"zt0\")";
958+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
959+
OS << " __arm_out(\"zt0\")";
960+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
961+
OS << " __arm_inout(\"zt0\")";
954962

955963
printFunctionAfter(Info, OS);
956964

clang/lib/CodeGen/CGCall.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,16 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
17821782
FuncAttrs.addAttribute("aarch64_pstate_za_shared");
17831783
FuncAttrs.addAttribute("aarch64_pstate_za_preserved");
17841784
}
1785+
1786+
// ZT0
1787+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
1788+
FuncAttrs.addAttribute("aarch64_zt0_preserved");
1789+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
1790+
FuncAttrs.addAttribute("aarch64_zt0_in");
1791+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
1792+
FuncAttrs.addAttribute("aarch64_zt0_out");
1793+
if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
1794+
FuncAttrs.addAttribute("aarch64_zt0_inout");
17851795
}
17861796

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

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
23842384
if (auto *Attr = D->getAttr<ArmNewAttr>()) {
23852385
if (Attr->isNewZA())
23862386
B.addAttribute("aarch64_pstate_za_new");
2387+
if (Attr->isNewZT0())
2388+
B.addAttribute("aarch64_zt0_new");
23872389
}
23882390

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

clang/lib/Sema/SemaChecking.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7544,6 +7544,28 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
75447544
if (!CallerHasZAState)
75457545
Diag(Loc, diag::err_sme_za_call_no_za_state);
75467546
}
7547+
7548+
// If the callee uses AArch64 SME ZT0 state but the caller doesn't define
7549+
// any, then this is an error.
7550+
FunctionType::ArmStateValue ArmZT0State =
7551+
FunctionType::getArmZT0State(ExtInfo.AArch64SMEAttributes);
7552+
if (ArmZT0State != FunctionType::ARM_None) {
7553+
bool CallerHasZT0State = false;
7554+
if (const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
7555+
auto *Attr = CallerFD->getAttr<ArmNewAttr>();
7556+
if (Attr && Attr->isNewZT0())
7557+
CallerHasZT0State = true;
7558+
else if (const auto *FPT =
7559+
CallerFD->getType()->getAs<FunctionProtoType>())
7560+
CallerHasZT0State =
7561+
FunctionType::getArmZT0State(
7562+
FPT->getExtProtoInfo().AArch64SMEAttributes) !=
7563+
FunctionType::ARM_None;
7564+
}
7565+
7566+
if (!CallerHasZT0State)
7567+
Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
7568+
}
75477569
}
75487570

75497571
if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12206,12 +12206,15 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
1220612206
const auto *Attr = NewFD->getAttr<ArmNewAttr>();
1220712207
bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
1220812208
bool UsesZA = Attr && Attr->isNewZA();
12209+
bool UsesZT0 = Attr && Attr->isNewZT0();
1220912210
if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
1221012211
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1221112212
UsesSM |=
1221212213
EPI.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
1221312214
UsesZA |= FunctionType::getArmZAState(EPI.AArch64SMEAttributes) !=
1221412215
FunctionType::ARM_None;
12216+
UsesZT0 |= FunctionType::getArmZT0State(EPI.AArch64SMEAttributes) !=
12217+
FunctionType::ARM_None;
1221512218
}
1221612219

1221712220
if (UsesSM || UsesZA) {
@@ -12226,6 +12229,14 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
1222612229
diag::err_sme_definition_using_za_in_non_sme_target);
1222712230
}
1222812231
}
12232+
if (UsesZT0) {
12233+
llvm::StringMap<bool> FeatureMap;
12234+
Context.getFunctionFeatureMap(FeatureMap, NewFD);
12235+
if (!FeatureMap.contains("sme2")) {
12236+
Diag(NewFD->getLocation(),
12237+
diag::err_sme_definition_using_zt0_in_non_sme2_target);
12238+
}
12239+
}
1222912240
}
1223012241

1223112242
return Redeclaration;

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8994,6 +8994,7 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
89948994
}
89958995

89968996
bool HasZA = false;
8997+
bool HasZT0 = false;
89978998
for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
89988999
StringRef StateName;
89999000
SourceLocation LiteralLoc;
@@ -9002,6 +9003,8 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
90029003

90039004
if (StateName == "za")
90049005
HasZA = true;
9006+
else if (StateName == "zt0")
9007+
HasZT0 = true;
90059008
else {
90069009
S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
90079010
AL.setInvalid();
@@ -9020,6 +9023,11 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
90209023
if (HasZA && ZAState != FunctionType::ARM_None &&
90219024
checkArmNewAttrMutualExclusion(S, AL, FPT, ZAState, "za"))
90229025
return;
9026+
FunctionType::ArmStateValue ZT0State =
9027+
FunctionType::getArmZT0State(FPT->getAArch64SMEAttributes());
9028+
if (HasZT0 && ZT0State != FunctionType::ARM_None &&
9029+
checkArmNewAttrMutualExclusion(S, AL, FPT, ZT0State, "zt0"))
9030+
return;
90239031
}
90249032

90259033
D->dropAttr<ArmNewAttr>();

clang/lib/Sema/SemaType.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7938,6 +7938,9 @@ static bool handleArmStateAttribute(Sema &S,
79387938
if (StateName == "za") {
79397939
Shift = FunctionType::SME_ZAShift;
79407940
ExistingState = FunctionType::getArmZAState(EPI.AArch64SMEAttributes);
7941+
} else if (StateName == "zt0") {
7942+
Shift = FunctionType::SME_ZT0Shift;
7943+
ExistingState = FunctionType::getArmZT0State(EPI.AArch64SMEAttributes);
79417944
} else {
79427945
S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
79437946
Attr.setInvalid();

0 commit comments

Comments
 (0)