Skip to content

[Clang][SveEmitter] Split up TargetGuard into SVE and SME component. #96482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 43 additions & 39 deletions clang/include/clang/Basic/arm_sme.td

Large diffs are not rendered by default.

231 changes: 109 additions & 122 deletions clang/include/clang/Basic/arm_sve.td

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion clang/include/clang/Basic/arm_sve_sme_incl.td
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,15 @@ class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
ImmCheckType Kind = kind;
}

defvar InvalidMode = "";

class Inst<string n, string p, string t, MergeType mt, string i,
list<FlagType> ft, list<ImmCheck> ch, MemEltType met = MemEltTyDefault> {
string Name = n;
string Prototype = p;
string Types = t;
string TargetGuard = "sve|sme";
string SVETargetGuard = "sve";
string SMETargetGuard = "sme";
int Merge = mt.Value;
string MergeSuffix = mt.Suffix;
string LLVMIntrinsic = i;
Expand Down
58 changes: 29 additions & 29 deletions clang/test/Sema/aarch64-sve-intrinsics/acle_sve_bfloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@

void test_bfloat(svbool_t pg, uint64_t u64, int64_t i64, const bfloat16_t *const_bf16_ptr, bfloat16_t *bf16_ptr, svbfloat16_t bf16, svbfloat16x2_t bf16x2, svbfloat16x3_t bf16x3, svbfloat16x4_t bf16x4)
{
// expected-error@+1 {{'svcreate2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svcreate2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svcreate2_bf16(bf16, bf16);
// expected-error@+1 {{'svcreate3_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svcreate3_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svcreate3_bf16(bf16, bf16, bf16);
// expected-error@+1 {{'svcreate4_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svcreate4_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svcreate4_bf16(bf16, bf16, bf16, bf16);
// expected-error@+1 {{'svget2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svget2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svget2_bf16(bf16x2, 1);
// expected-error@+1 {{'svget3_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svget3_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svget3_bf16(bf16x3, 1);
// expected-error@+1 {{'svget4_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svget4_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svget4_bf16(bf16x4, 1);
// expected-error@+1 {{'svld1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svld1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svld1_bf16(pg, const_bf16_ptr);
// expected-error@+1 {{'svld1_vnum_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svld1_vnum_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svld1_vnum_bf16(pg, const_bf16_ptr, i64);
// expected-error@+1 {{'svld1rq_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svld1rq_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svld1rq_bf16(pg, const_bf16_ptr);
// expected-error@+1 {{'svldff1_bf16' needs target feature sve,bf16}}
svldff1_bf16(pg, const_bf16_ptr);
Expand All @@ -32,55 +32,55 @@ void test_bfloat(svbool_t pg, uint64_t u64, int64_t i64, const bfloat16_t *const
svldnf1_bf16(pg, const_bf16_ptr);
// expected-error@+1 {{'svldnf1_vnum_bf16' needs target feature sve,bf16}}
svldnf1_vnum_bf16(pg, const_bf16_ptr, i64);
// expected-error@+1 {{'svldnt1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svldnt1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svldnt1_bf16(pg, const_bf16_ptr);
// expected-error@+1 {{'svldnt1_vnum_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svldnt1_vnum_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svldnt1_vnum_bf16(pg, const_bf16_ptr, i64);
// expected-error@+1 {{'svrev_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svrev_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svrev_bf16(bf16);
// expected-error@+1 {{'svset2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svset2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svset2_bf16(bf16x2, 1, bf16);
// expected-error@+1 {{'svset3_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svset3_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svset3_bf16(bf16x3, 1, bf16);
// expected-error@+1 {{'svset4_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svset4_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svset4_bf16(bf16x4, 1, bf16);
// expected-error@+1 {{'svst1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svst1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svst1_bf16(pg, bf16_ptr, bf16);
// expected-error@+1 {{'svst1_vnum_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svst1_vnum_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svst1_vnum_bf16(pg, bf16_ptr, i64, bf16);
// expected-error@+1 {{'svstnt1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svstnt1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svstnt1_bf16(pg, bf16_ptr, bf16);
// expected-error@+1 {{'svstnt1_vnum_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svstnt1_vnum_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svstnt1_vnum_bf16(pg, bf16_ptr, i64, bf16);
// expected-error@+1 {{'svtrn1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svtrn1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svtrn1_bf16(bf16, bf16);
// expected-error@+1 {{'svtrn1q_bf16' needs target feature sve,bf16}}
svtrn1q_bf16(bf16, bf16);
// expected-error@+1 {{'svtrn2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svtrn2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svtrn2_bf16(bf16, bf16);
// expected-error@+1 {{'svtrn2q_bf16' needs target feature sve,bf16}}
svtrn2q_bf16(bf16, bf16);
// expected-error@+1 {{'svundef_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svundef_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svundef_bf16();
// expected-error@+1 {{'svundef2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svundef2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svundef2_bf16();
// expected-error@+1 {{'svundef3_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svundef3_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svundef3_bf16();
// expected-error@+1 {{'svundef4_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svundef4_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svundef4_bf16();
// expected-error@+1 {{'svuzp1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svuzp1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svuzp1_bf16(bf16, bf16);
// expected-error@+1 {{'svuzp1q_bf16' needs target feature sve,bf16}}
svuzp1q_bf16(bf16, bf16);
// expected-error@+1 {{'svuzp2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svuzp2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svuzp2_bf16(bf16, bf16);
// expected-error@+1 {{'svuzp2q_bf16' needs target feature sve,bf16}}
svuzp2q_bf16(bf16, bf16);
// expected-error@+1 {{'svzip1_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svzip1_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svzip1_bf16(bf16, bf16);
// expected-error@+1 {{'svzip1q_bf16' needs target feature sve,bf16}}
svzip1q_bf16(bf16, bf16);
// expected-error@+1 {{'svzip2_bf16' needs target feature (sve|sme),bf16}}
// expected-error@+1 {{'svzip2_bf16' needs target feature (sve,bf16)|(sme,bf16)}}
svzip2_bf16(bf16, bf16);
// expected-error@+1 {{'svzip2q_bf16' needs target feature sve,bf16}}
svzip2q_bf16(bf16, bf16);
Expand Down
16 changes: 8 additions & 8 deletions clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_bfloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

void test_bfloat(const bfloat16_t *const_bf16_ptr, svbfloat16_t bf16, svbfloat16x2_t bf16x2)
{
// expected-error@+2 {{'svwhilerw_bf16' needs target feature (sve2|sme),bf16}}
// overload-error@+1 {{'svwhilerw' needs target feature (sve2|sme),bf16}}
// expected-error@+2 {{'svwhilerw_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilerw' needs target feature (sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svwhilerw,_bf16,,)(const_bf16_ptr, const_bf16_ptr);
// expected-error@+2 {{'svtbx_bf16' needs target feature (sve2|sme),bf16}}
// overload-error@+1 {{'svtbx' needs target feature (sve2|sme),bf16}}
// expected-error@+2 {{'svtbx_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbx' needs target feature (sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svtbx,_bf16,,)(bf16, bf16, svundef_u16());
// expected-error@+2 {{'svtbl2_bf16' needs target feature (sve2|sme),bf16}}
// overload-error@+1 {{'svtbl2' needs target feature (sve2|sme),bf16}}
// expected-error@+2 {{'svtbl2_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbl2' needs target feature (sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svtbl2,_bf16,,)(bf16x2, svundef_u16());
// expected-error@+2 {{'svwhilewr_bf16' needs target feature (sve2|sme),bf16}}
// overload-error@+1 {{'svwhilewr' needs target feature (sve2|sme),bf16}}
// expected-error@+2 {{'svwhilewr_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilewr' needs target feature (sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svwhilewr,_bf16,,)(const_bf16_ptr, const_bf16_ptr);
}
71 changes: 49 additions & 22 deletions clang/utils/TableGen/SveEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class Intrinsic {
ClassKind Class;

/// The architectural #ifdef guard.
std::string Guard;
std::string SVEGuard, SMEGuard;

// The merge suffix such as _m, _x or _z.
std::string MergeSuffix;
Expand All @@ -184,7 +184,8 @@ class Intrinsic {
Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
StringRef MergeSuffix, uint64_t MemoryElementTy, StringRef LLVMName,
uint64_t Flags, ArrayRef<ImmCheck> ImmChecks, TypeSpec BT,
ClassKind Class, SVEEmitter &Emitter, StringRef Guard);
ClassKind Class, SVEEmitter &Emitter, StringRef SVEGuard,
StringRef SMEGuard);

~Intrinsic()=default;

Expand All @@ -194,7 +195,27 @@ class Intrinsic {
TypeSpec getBaseTypeSpec() const { return BaseTypeSpec; }
SVEType getBaseType() const { return BaseType; }

StringRef getGuard() const { return Guard; }
StringRef getSVEGuard() const { return SVEGuard; }
StringRef getSMEGuard() const { return SMEGuard; }
void printGuard(raw_ostream &OS) const {
if (!SVEGuard.empty() && SMEGuard.empty())
OS << SVEGuard;
else if (SVEGuard.empty() && !SMEGuard.empty())
OS << SMEGuard;
else {
if (SVEGuard.find(",") != std::string::npos ||
SVEGuard.find("|") != std::string::npos)
OS << "(" << SVEGuard << ")";
else
OS << SVEGuard;
OS << "|";
if (SMEGuard.find(",") != std::string::npos ||
SMEGuard.find("|") != std::string::npos)
OS << "(" << SMEGuard << ")";
else
OS << SMEGuard;
}
}
ClassKind getClassKind() const { return Class; }

SVEType getReturnType() const { return Types[0]; }
Expand Down Expand Up @@ -943,11 +964,12 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
StringRef MergeSuffix, uint64_t MemoryElementTy,
StringRef LLVMName, uint64_t Flags,
ArrayRef<ImmCheck> Checks, TypeSpec BT, ClassKind Class,
SVEEmitter &Emitter, StringRef Guard)
SVEEmitter &Emitter, StringRef SVEGuard,
StringRef SMEGuard)
: Name(Name.str()), LLVMName(LLVMName), Proto(Proto.str()),
BaseTypeSpec(BT), Class(Class), Guard(Guard.str()),
MergeSuffix(MergeSuffix.str()), BaseType(BT, 'd'), Flags(Flags),
ImmChecks(Checks.begin(), Checks.end()) {
BaseTypeSpec(BT), Class(Class), SVEGuard(SVEGuard.str()),
SMEGuard(SMEGuard.str()), MergeSuffix(MergeSuffix.str()),
BaseType(BT, 'd'), Flags(Flags), ImmChecks(Checks.begin(), Checks.end()) {
// Types[0] is the return value.
for (unsigned I = 0; I < (getNumParams() + 1); ++I) {
char Mod;
Expand Down Expand Up @@ -1147,7 +1169,8 @@ void SVEEmitter::createIntrinsic(
StringRef Name = R->getValueAsString("Name");
StringRef Proto = R->getValueAsString("Prototype");
StringRef Types = R->getValueAsString("Types");
StringRef Guard = R->getValueAsString("TargetGuard");
StringRef SVEGuard = R->getValueAsString("SVETargetGuard");
StringRef SMEGuard = R->getValueAsString("SMETargetGuard");
StringRef LLVMName = R->getValueAsString("LLVMIntrinsic");
uint64_t Merge = R->getValueAsInt("Merge");
StringRef MergeSuffix = R->getValueAsString("MergeSuffix");
Expand Down Expand Up @@ -1203,13 +1226,13 @@ void SVEEmitter::createIntrinsic(

Out.push_back(std::make_unique<Intrinsic>(
Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags, ImmChecks,
TS, ClassS, *this, Guard));
TS, ClassS, *this, SVEGuard, SMEGuard));

// Also generate the short-form (e.g. svadd_m) for the given type-spec.
if (Intrinsic::isOverloadedIntrinsic(Name))
Out.push_back(std::make_unique<Intrinsic>(
Name, Proto, Merge, MergeSuffix, MemEltType, LLVMName, Flags,
ImmChecks, TS, ClassG, *this, Guard));
ImmChecks, TS, ClassG, *this, SVEGuard, SMEGuard));
}
}

Expand All @@ -1229,9 +1252,9 @@ void SVEEmitter::createCoreHeaderIntrinsics(raw_ostream &OS,
[](const std::unique_ptr<Intrinsic> &A,
const std::unique_ptr<Intrinsic> &B) {
auto ToTuple = [](const std::unique_ptr<Intrinsic> &I) {
return std::make_tuple(I->getGuard(),
(unsigned)I->getClassKind(),
I->getName());
return std::make_tuple(
I->getSVEGuard().str() + I->getSMEGuard().str(),
(unsigned)I->getClassKind(), I->getName());
};
return ToTuple(A) < ToTuple(B);
});
Expand Down Expand Up @@ -1434,10 +1457,12 @@ void SVEEmitter::createBuiltins(raw_ostream &OS) {
for (auto &Def : Defs) {
// Only create BUILTINs for non-overloaded intrinsics, as overloaded
// declarations only live in the header file.
if (Def->getClassKind() != ClassG)
if (Def->getClassKind() != ClassG) {
OS << "TARGET_BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \""
<< Def->getBuiltinTypeStr() << "\", \"n\", \"" << Def->getGuard()
<< "\")\n";
<< Def->getBuiltinTypeStr() << "\", \"n\", \"";
Def->printGuard(OS);
OS << "\")\n";
}
}

// Add reinterpret functions.
Expand Down Expand Up @@ -1638,10 +1663,12 @@ void SVEEmitter::createSMEBuiltins(raw_ostream &OS) {
for (auto &Def : Defs) {
// Only create BUILTINs for non-overloaded intrinsics, as overloaded
// declarations only live in the header file.
if (Def->getClassKind() != ClassG)
if (Def->getClassKind() != ClassG) {
OS << "TARGET_BUILTIN(__builtin_sme_" << Def->getMangledName() << ", \""
<< Def->getBuiltinTypeStr() << "\", \"n\", \"" << Def->getGuard()
<< "\")\n";
<< Def->getBuiltinTypeStr() << "\", \"n\", \"";
Def->printGuard(OS);
OS << "\")\n";
}
}

OS << "#endif\n\n";
Expand Down Expand Up @@ -1783,9 +1810,9 @@ void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) {
getEnumValueForFlag("IsStreamingCompatible");

for (auto &Def : Defs) {
if (!Def->isFlagSet(VerifyRuntimeMode) && Def->getGuard().contains("sve") &&
Def->getGuard().contains("sme"))
llvm_unreachable("Missing VerifyRuntimeMode flag");
if (!Def->isFlagSet(VerifyRuntimeMode) && !Def->getSVEGuard().empty() &&
!Def->getSMEGuard().empty())
report_fatal_error("Missing VerifyRuntimeMode flag");

if (Def->isFlagSet(IsStreamingFlag))
StreamingMap["ArmStreaming"].insert(Def->getMangledName());
Expand Down
Loading