Skip to content
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

[Clang][SME2] Add multi-vector add/sub builtins #69725

Merged
merged 7 commits into from
Nov 7, 2023
Prev Previous commit
Next Next commit
- Rename GetAArch64SMEProcessedOperands to GetAArch64SVEProcessedOper…
…ands

- Removed code checking for ICEArguments from EmitAArch64SMEBuiltinExpr
- Added comment over check for IsTupleGetOrSet
- Added the code to print SME attributes back into emitIntrinsic
  • Loading branch information
kmclaughlin-arm committed Nov 2, 2023
commit 2c64efea927730852d6b7b4890130d9f46a78b94
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
@@ -4298,7 +4298,7 @@ class CodeGenFunction : public CodeGenTypeCache {
/// for struct of scalable vectors if a function returns struct.
llvm::Value *FormSVEBuiltinResult(llvm::Value *Call);

void GetAArch64SMEProcessedOperands(unsigned BuiltinID, const CallExpr *E,
void GetAArch64SVEProcessedOperands(unsigned BuiltinID, const CallExpr *E,
SmallVectorImpl<llvm::Value *> &Ops,
SVETypeFlags TypeFlags);

34 changes: 25 additions & 9 deletions clang/utils/TableGen/SveEmitter.cpp
Original file line number Diff line number Diff line change
@@ -248,7 +248,7 @@ class Intrinsic {
}

/// Emits the intrinsic declaration to the ostream.
void emitIntrinsic(raw_ostream &OS, ACLEKind Kind) const;
void emitIntrinsic(raw_ostream &OS, SVEEmitter &Emitter, ACLEKind Kind) const;

private:
std::string getMergeSuffix() const { return MergeSuffix; }
@@ -357,7 +357,7 @@ class SVEEmitter {
void createHeader(raw_ostream &o);

// Emits core intrinsics in both arm_sme.h and arm_sve.h
void createCoreHeaderIntrinsics(raw_ostream &o, ACLEKind Kind);
void createCoreHeaderIntrinsics(raw_ostream &o, SVEEmitter &Emitter, ACLEKind Kind);
kmclaughlin-arm marked this conversation as resolved.
Show resolved Hide resolved

/// Emit all the __builtin prototypes and code needed by Sema.
void createBuiltins(raw_ostream &o);
@@ -1028,25 +1028,39 @@ std::string Intrinsic::mangleName(ClassKind LocalCK) const {
getMergeSuffix();
}

void Intrinsic::emitIntrinsic(raw_ostream &OS, ACLEKind Kind) const {
void Intrinsic::emitIntrinsic(raw_ostream &OS, SVEEmitter &Emitter,
ACLEKind Kind) const {
bool IsOverloaded = getClassKind() == ClassG && getProto().size() > 1;

std::string FullName = mangleName(ClassS);
std::string ProtoName = mangleName(getClassKind());
std::string SMEAttrs = "";

if (Flags & Emitter.getEnumValueForFlag("IsStreaming"))
SMEAttrs += ", arm_streaming";
if (Flags & Emitter.getEnumValueForFlag("IsStreamingCompatible"))
SMEAttrs += ", arm_streaming_compatible";
if (Flags & Emitter.getEnumValueForFlag("IsSharedZA"))
SMEAttrs += ", arm_shared_za";
if (Flags & Emitter.getEnumValueForFlag("IsPreservesZA"))
SMEAttrs += ", arm_preserves_za";

OS << (IsOverloaded ? "__aio " : "__ai ")
<< "__attribute__((__clang_arm_builtin_alias(";

switch (Kind) {
case ACLEKind::SME:
OS << "__builtin_sme_" << FullName << ")))\n";
OS << "__builtin_sme_" << FullName << ")";
break;
case ACLEKind::SVE:
OS << "__builtin_sve_" << FullName << ")))\n";
OS << "__builtin_sve_" << FullName << ")";
break;
}

if (!SMEAttrs.empty())
OS << SMEAttrs;
OS << "))\n";

OS << getTypes()[0].str() << " " << ProtoName << "(";
for (unsigned I = 0; I < getTypes().size() - 1; ++I) {
if (I != 0)
@@ -1180,7 +1194,9 @@ void SVEEmitter::createIntrinsic(
}
}

void SVEEmitter::createCoreHeaderIntrinsics(raw_ostream &OS, ACLEKind Kind) {
void SVEEmitter::createCoreHeaderIntrinsics(raw_ostream &OS,
SVEEmitter &Emitter,
ACLEKind Kind) {
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
for (auto *R : RV)
@@ -1201,7 +1217,7 @@ void SVEEmitter::createCoreHeaderIntrinsics(raw_ostream &OS, ACLEKind Kind) {

// Actually emit the intrinsic declarations.
for (auto &I : Defs)
I->emitIntrinsic(OS, Kind);
I->emitIntrinsic(OS, Emitter, Kind);
}

void SVEEmitter::createHeader(raw_ostream &OS) {
@@ -1355,7 +1371,7 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
<< To.Suffix << "(__VA_ARGS__)\n";
}

createCoreHeaderIntrinsics(OS, ACLEKind::SVE);
createCoreHeaderIntrinsics(OS, *this, ACLEKind::SVE);

OS << "#define svcvtnt_bf16_x svcvtnt_bf16_m\n";
OS << "#define svcvtnt_bf16_f32_x svcvtnt_bf16_f32_m\n";
@@ -1537,7 +1553,7 @@ void SVEEmitter::createSMEHeader(raw_ostream &OS) {
OS << "extern \"C\" {\n";
OS << "#endif\n\n";

createCoreHeaderIntrinsics(OS, ACLEKind::SME);
createCoreHeaderIntrinsics(OS, *this, ACLEKind::SME);

OS << "#ifdef __cplusplus\n";
OS << "} // extern \"C\"\n";