-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
[RISCV][FMV] Support target_version #99040
Conversation
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-backend-risc-v Author: Piyou Chen (BeMg) ChangesThis patch enable The proposal of
Patch is 91.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99040.diff 22 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 12a4617c64d87..b2b63674ecc07 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -375,4 +375,8 @@ def warn_missing_symbol_graph_dir : Warning<
def err_ast_action_on_llvm_ir : Error<
"cannot apply AST actions to LLVM IR file '%0'">,
DefaultFatal;
+
+def err_os_unsupport_riscv_target_clones : Error<
+ "target_clones is currently only supported on Linux">;
+
}
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index cf7628553647c..40fbc3a1116cb 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1519,7 +1519,8 @@ class TargetInfo : public TransferrableTargetInfo,
/// Identify whether this target supports multiversioning of functions,
/// which requires support for cpu_supports and cpu_is functionality.
bool supportsMultiVersioning() const {
- return getTriple().isX86() || getTriple().isAArch64();
+ return getTriple().isX86() || getTriple().isAArch64() ||
+ getTriple().isRISCV();
}
/// Identify whether this target supports IFuncs.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8e35e71d4a23e..e0d3fa514a049 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13839,6 +13839,18 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
+ } else if (Target->getTriple().isRISCV()) {
+ StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
+ std::vector<std::string> Features;
+ if (VersionStr != "default") {
+ ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(VersionStr);
+ Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ ParsedAttr.Features.end());
+ }
+ Features.insert(Features.begin(),
+ Target->getTargetOpts().FeaturesAsWritten.begin(),
+ Target->getTargetOpts().FeaturesAsWritten.end());
+ Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
} else {
std::vector<std::string> Features;
StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
@@ -13849,9 +13861,16 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
}
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
- llvm::SmallVector<StringRef, 8> Feats;
- TV->getFeatures(Feats);
- std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
+ std::vector<std::string> Features;
+ if (Target->getTriple().isRISCV()) {
+ ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(TV->getName());
+ Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ ParsedAttr.Features.end());
+ } else {
+ llvm::SmallVector<StringRef, 8> Feats;
+ TV->getFeatures(Feats);
+ Features = getFMVBackendFeaturesFor(Feats);
+ }
Features.insert(Features.begin(),
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 6cc0d9485720c..83ad64cb1cc3c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -62,6 +62,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/TargetParser/X86TargetParser.h"
#include <optional>
#include <sstream>
@@ -14214,6 +14215,16 @@ Value *CodeGenFunction::EmitAArch64CpuInit() {
return Builder.CreateCall(Func);
}
+Value *CodeGenFunction::EmitRISCVCpuInit() {
+ llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
+ llvm::FunctionCallee Func =
+ CGM.CreateRuntimeFunction(FTy, "__init_riscv_features_bits");
+ cast<llvm::GlobalValue>(Func.getCallee())->setDSOLocal(true);
+ cast<llvm::GlobalValue>(Func.getCallee())
+ ->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+ return Builder.CreateCall(Func);
+}
+
Value *CodeGenFunction::EmitX86CpuInit() {
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
/*Variadic*/ false);
@@ -14266,6 +14277,73 @@ CodeGenFunction::EmitAArch64CpuSupports(ArrayRef<StringRef> FeaturesStrs) {
return Result;
}
+Value *CodeGenFunction::EmitRISCVCpuSupports(ArrayRef<StringRef> FeaturesStrs,
+ unsigned &MaxGroupIDUsed) {
+
+ const unsigned FeatureBitSize = llvm::RISCV::RISCVFeatureBitSize;
+ llvm::ArrayType *ArrayOfInt64Ty =
+ llvm::ArrayType::get(Int64Ty, FeatureBitSize);
+ llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty);
+ llvm::Constant *RISCVFeaturesBits =
+ CGM.CreateRuntimeVariable(StructTy, "__riscv_feature_bits");
+ cast<llvm::GlobalValue>(RISCVFeaturesBits)->setDSOLocal(true);
+
+ auto LoadFeatureBit = [&](unsigned Index) {
+ // Create GEP then load.
+ Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index);
+ std::vector<llvm::Value *> GEPIndices = {llvm::ConstantInt::get(Int32Ty, 0),
+ llvm::ConstantInt::get(Int32Ty, 1),
+ IndexVal};
+ Value *Ptr =
+ Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices);
+ Value *FeaturesBit =
+ Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8));
+ return FeaturesBit;
+ };
+
+ SmallVector<unsigned long long> RequireFeatureBits =
+ llvm::RISCV::getRequireFeatureBitMask(FeaturesStrs);
+ Value *Result = Builder.getTrue();
+ for (unsigned i = 0; i < RequireFeatureBits.size(); i++) {
+ if (!RequireFeatureBits[i])
+ continue;
+ MaxGroupIDUsed = i;
+ Value *Mask = Builder.getInt64(RequireFeatureBits[i]);
+ Value *Bitset = Builder.CreateAnd(LoadFeatureBit(i), Mask);
+ Value *Cmp = Builder.CreateICmpEQ(Bitset, Mask);
+ Result = Builder.CreateAnd(Result, Cmp);
+ }
+
+ return Result;
+}
+
+Value *CodeGenFunction::EmitRISCVFeatureBitsLength(unsigned MaxGroupIDUsed) {
+
+ const unsigned FeatureBitSize = llvm::RISCV::RISCVFeatureBitSize;
+ llvm::ArrayType *ArrayOfInt64Ty =
+ llvm::ArrayType::get(Int64Ty, FeatureBitSize);
+ llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty);
+ llvm::Constant *RISCVFeaturesBits =
+ CGM.CreateRuntimeVariable(StructTy, "__riscv_feature_bits");
+ cast<llvm::GlobalValue>(RISCVFeaturesBits)->setDSOLocal(true);
+
+ auto LoadMaxGroupID = [&]() {
+ std::vector<llvm::Value *> GEPIndices = {
+ llvm::ConstantInt::get(Int32Ty, 0), llvm::ConstantInt::get(Int32Ty, 0)};
+ llvm::Value *Ptr =
+ Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices);
+ Value *Length =
+ Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8));
+ return Length;
+ };
+
+ Value *UsedMaxGroupID = Builder.getInt64(MaxGroupIDUsed);
+ Value *GroupIDResult =
+ Builder.CreateICmpULT(UsedMaxGroupID, LoadMaxGroupID());
+
+ return GroupIDResult;
+}
+
Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
if (BuiltinID == Builtin::BI__builtin_cpu_is)
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 26deeca95d326..f2b2915878a90 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2854,12 +2854,101 @@ void CodeGenFunction::EmitMultiVersionResolver(
case llvm::Triple::aarch64:
EmitAArch64MultiVersionResolver(Resolver, Options);
return;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ EmitRISCVMultiVersionResolver(Resolver, Options);
+ return;
default:
- assert(false && "Only implemented for x86 and AArch64 targets");
+ assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
}
}
+void CodeGenFunction::EmitRISCVMultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
+
+ if (getContext().getTargetInfo().getTriple().getOS() !=
+ llvm::Triple::OSType::Linux) {
+ CGM.getDiags().Report(diag::err_os_unsupport_riscv_target_clones);
+ return;
+ }
+
+ llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
+ Builder.SetInsertPoint(CurBlock);
+ EmitRISCVCpuInit();
+
+ bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
+ bool HasDefault = false;
+ int DefaultIndex = 0;
+ // Check the each candidate function.
+ for (unsigned Index = 0; Index < Options.size(); Index++) {
+
+ if (Options[Index].Conditions.Features[0].starts_with("default")) {
+ HasDefault = true;
+ DefaultIndex = Index;
+ continue;
+ }
+
+ Builder.SetInsertPoint(CurBlock);
+
+ std::vector<std::string> TargetAttrFeats =
+ getContext()
+ .getTargetInfo()
+ .parseTargetAttr(Options[Index].Conditions.Features[0])
+ .Features;
+
+ if (!TargetAttrFeats.empty()) {
+
+ llvm::BasicBlock *SecondCond =
+ createBasicBlock("resovler_cond", Resolver);
+
+ Builder.SetInsertPoint(SecondCond);
+ unsigned MaxGroupIDUsed = 0;
+ llvm::SmallVector<StringRef, 8> CurrTargetAttrFeats;
+
+ for (auto Feat : TargetAttrFeats)
+ CurrTargetAttrFeats.push_back(StringRef(Feat).substr(1));
+
+ llvm::Value *SecondCondition =
+ EmitRISCVCpuSupports(CurrTargetAttrFeats, MaxGroupIDUsed);
+
+ Builder.SetInsertPoint(CurBlock);
+ llvm::Value *FirstCondition = EmitRISCVFeatureBitsLength(MaxGroupIDUsed);
+
+ llvm::BasicBlock *RetBlock =
+ createBasicBlock("resolver_return", Resolver);
+ CGBuilderTy RetBuilder(*this, RetBlock);
+ CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder,
+ Options[Index].Function, SupportsIFunc);
+ llvm::BasicBlock *ElseBlock = createBasicBlock("resolver_else", Resolver);
+
+ Builder.SetInsertPoint(CurBlock);
+ Builder.CreateCondBr(FirstCondition, SecondCond, ElseBlock);
+
+ Builder.SetInsertPoint(SecondCond);
+ Builder.CreateCondBr(SecondCondition, RetBlock, ElseBlock);
+
+ CurBlock = ElseBlock;
+ }
+ }
+
+ // Finally, emit the default one.
+ if (HasDefault) {
+ Builder.SetInsertPoint(CurBlock);
+ CreateMultiVersionResolverReturn(
+ CGM, Resolver, Builder, Options[DefaultIndex].Function, SupportsIFunc);
+ return;
+ }
+
+ // If no generic/default, emit an unreachable.
+ Builder.SetInsertPoint(CurBlock);
+ llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+ TrapCall->setDoesNotReturn();
+ TrapCall->setDoesNotThrow();
+ Builder.CreateUnreachable();
+ Builder.ClearInsertionPoint();
+}
+
void CodeGenFunction::EmitAArch64MultiVersionResolver(
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
assert(!Options.empty() && "No multiversion resolver options found");
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 13f12b5d878a6..107701d3f1faa 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5291,6 +5291,9 @@ class CodeGenFunction : public CodeGenTypeCache {
void
EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
ArrayRef<MultiVersionResolverOption> Options);
+ void
+ EmitRISCVMultiVersionResolver(llvm::Function *Resolver,
+ ArrayRef<MultiVersionResolverOption> Options);
private:
QualType getVarArgType(const Expr *Arg);
@@ -5315,6 +5318,10 @@ class CodeGenFunction : public CodeGenTypeCache {
FormAArch64ResolverCondition(const MultiVersionResolverOption &RO);
llvm::Value *EmitAArch64CpuSupports(const CallExpr *E);
llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs);
+ llvm::Value *EmitRISCVCpuInit();
+ llvm::Value *EmitRISCVCpuSupports(ArrayRef<StringRef> FeatureStrs,
+ unsigned &MaxGroupIDUsed);
+ llvm::Value *EmitRISCVFeatureBitsLength(unsigned MaxGroupIDUsed);
};
inline DominatingLLVMValue::saved_type
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 5c810cd332185..c65283960fc6e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4243,8 +4243,15 @@ void CodeGenModule::emitMultiVersionFunctions() {
CurFD->doesThisDeclarationHaveABody();
HasDefaultDecl |= TVA->isDefaultVersion();
ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef);
- TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
+ if (getTarget().getTriple().isRISCV()) {
+ llvm::AttrBuilder FuncAttrs(Func->getContext());
+ ParsedTargetAttr PTA =
+ getTarget().parseTargetAttr(TVA->getName());
+ Feats.push_back(TVA->getName());
+ } else {
+ TVA->getFeatures(Feats);
+ }
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
ShouldEmitResolver |= CurFD->doesThisDeclarationHaveABody();
@@ -4257,7 +4264,10 @@ void CodeGenModule::emitMultiVersionFunctions() {
Feats.clear();
if (getTarget().getTriple().isAArch64())
TC->getFeatures(Feats, I);
- else {
+ else if (getTarget().getTriple().isRISCV()) {
+ StringRef Version = TC->getFeatureStr(I);
+ Feats.push_back(Version);
+ } else {
StringRef Version = TC->getFeatureStr(I);
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index f2add9351c03c..ba81bf7d1dd0a 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -63,9 +63,32 @@ class RISCVABIInfo : public DefaultABIInfo {
CharUnits Field2Off) const;
ABIArgInfo coerceVLSVector(QualType Ty) const;
+
+ using ABIInfo::appendAttributeMangling;
+ void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
+ raw_ostream &Out) const override;
+ void appendAttributeMangling(StringRef AttrStr,
+ raw_ostream &Out) const override;
};
} // end anonymous namespace
+void RISCVABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
+ unsigned Index,
+ raw_ostream &Out) const {
+ appendAttributeMangling(Attr->getFeatureStr(Index), Out);
+}
+
+void RISCVABIInfo::appendAttributeMangling(StringRef AttrStr,
+ raw_ostream &Out) const {
+ if (AttrStr == "default") {
+ Out << ".default";
+ return;
+ }
+
+ Out << '.';
+ Out << AttrStr;
+}
+
void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
QualType RetTy = FI.getReturnType();
if (!getCXXABI().classifyReturnType(FI))
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 66eeaa8e6f777..fd3af45114110 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10259,8 +10259,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Handle attributes.
ProcessDeclAttributes(S, NewFD, D);
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
- if (NewTVA && !NewTVA->isDefaultVersion() &&
- !Context.getTargetInfo().hasFeature("fmv")) {
+ if (Context.getTargetInfo().getTriple().isRISCV()) {
+ // Go thought anyway.
+ } else if (NewTVA && !NewTVA->isDefaultVersion() &&
+ !Context.getTargetInfo().hasFeature("fmv")) {
// Don't add to scope fmv functions declarations if fmv disabled
AddToScope = false;
return NewFD;
@@ -10967,13 +10969,27 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) {
}
if (TVA) {
- llvm::SmallVector<StringRef, 8> Feats;
- TVA->getFeatures(Feats);
- for (const auto &Feat : Feats) {
- if (!TargetInfo.validateCpuSupports(Feat)) {
- S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
- << Feature << Feat;
- return true;
+ if (S.getASTContext().getTargetInfo().getTriple().isRISCV()) {
+ ParsedTargetAttr ParseInfo =
+ S.getASTContext().getTargetInfo().parseTargetAttr(TVA->getName());
+ for (const auto &Feat : ParseInfo.Features) {
+ StringRef BareFeat = StringRef{Feat}.substr(1);
+
+ if (!TargetInfo.isValidFeatureName(BareFeat)) {
+ S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
+ << Feature << BareFeat;
+ return true;
+ }
+ }
+ } else {
+ llvm::SmallVector<StringRef, 8> Feats;
+ TVA->getFeatures(Feats);
+ for (const auto &Feat : Feats) {
+ if (!TargetInfo.validateCpuSupports(Feat)) {
+ S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
+ << Feature << Feat;
+ return true;
+ }
}
}
}
@@ -11238,7 +11254,8 @@ static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
}
static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
- if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
+ if (!From->getASTContext().getTargetInfo().getTriple().isAArch64() &&
+ !From->getASTContext().getTargetInfo().getTriple().isRISCV())
return;
MultiVersionKind MVKindFrom = From->getMultiVersionKind();
@@ -15418,8 +15435,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
FD->setInvalidDecl();
}
if (const auto *Attr = FD->getAttr<TargetVersionAttr>()) {
- if (!Context.getTargetInfo().hasFeature("fmv") &&
- !Attr->isDefaultVersion()) {
+ if (Context.getTargetInfo().getTriple().isRISCV()) {
+ // pass thought anyway.
+ } else if (!Context.getTargetInfo().hasFeature("fmv") &&
+ !Attr->isDefaultVersion()) {
// If function multi versioning disabled skip parsing function body
// defined with non-default target_version attribute
if (SkipBody)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f2cd46d1e7c93..d624e69c78084 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3015,6 +3015,21 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
enum SecondParam { None };
enum ThirdParam { Target, TargetClones, TargetVersion };
llvm::SmallVector<StringRef, 8> Features;
+ if (Context.getTargetInfo().getTriple().isRISCV()) {
+
+ if (AttrStr.starts_with("default"))
+ return false;
+
+ ParsedTargetAttr ParsedAttrs =
+ Context.getTargetInfo().parseTargetAttr(AttrStr);
+
+ if (AttrStr.starts_with("arch=+") &&
+ (!ParsedAttrs.Features.empty() || !ParsedAttrs.Tune.empty()))
+ return false;
+
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << AttrStr << TargetVersion;
+ }
AttrStr.split(Features, "+");
for (auto &CurFeature : Features) {
CurFeature = CurFeature.trim();
@@ -3127,6 +3142,32 @@ bool Sema::checkTargetClonesAttrString(
/*IncludeLocallyStreaming=*/false))
return Diag(LiteralLoc,
diag::err_sme_streaming_cannot_be_multiversioned);
+ } else if (...
[truncated]
|
32e2a27
to
e761914
Compare
3abf760
to
af2ba0f
Compare
Support |
stack on #85786 |
af2ba0f
to
54b5d68
Compare
Rebase to main |
clang/lib/Sema/SemaDecl.cpp
Outdated
@@ -10319,8 +10319,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, | |||
// Handle attributes. | |||
ProcessDeclAttributes(S, NewFD, D); | |||
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>(); | |||
if (NewTVA && !NewTVA->isDefaultVersion() && | |||
!Context.getTargetInfo().hasFeature("fmv")) { | |||
if (Context.getTargetInfo().getTriple().isRISCV()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you happen to know what the "fmv" feature is? I don't have context here. Any docs, or a good starting point in the code to understand what we're leaving out here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understand is the fmv
is a aarch64 feature to control the function multi-versioning. They(target_version and fmv) are both be introduced by this commit.
The ACLE spec and review comment can help to understand the context.
Additionally, it is treated as a generic option in the Clang command-line options, and it was also introduced in the same commit.
Do you think it's a good idea to add this similar feature to RISC-V, or should we just skip it?
S.Diag(FD->getLocation(), diag::err_bad_multiversion_option) | ||
<< Feature << Feat; | ||
return true; | ||
if (S.getASTContext().getTargetInfo().getTriple().isRISCV()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The need to version all of this by target is unfortunate. Is there a way we can reduce the duplication here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reduce the part of duplication, and the remain part is causing by different syntax between aarch64 and RISC-V.
To reducing the remain part of duplication, we could implement the RISC-V syntax inside clang/include/clang/Basic/Attr.td getFeatures
or make Aarch64 using the AArch64TargetInfo::parseTargetAttr
for target_version, or make something like parseTargetVersionAttr
hook here.
By the way, the parsing of target_clones syntax is controlled by the target. (Reference:
llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
Line 3121 in 9cd9377
if (TInfo.getTriple().isAArch64()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/7052 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/40/builds/2132 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/169/builds/3933 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/25/builds/3046 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/52/builds/2670 Here is the relevant piece of the build log for the reference
|
This patch enable `target_version` attribute for RISC-V target. The proposal of `target_version` syntax can be found at the riscv-non-isa/riscv-c-api-doc#48 (which has landed), as modified by the proposed riscv-non-isa/riscv-c-api-doc#85 (which adds the priority syntax). `target_version` attribute will trigger the function multi-versioning feature and act like `target_clones` attribute. See llvm#85786 for the implementation of `target_clones`.
This patch enable
target_version
attribute for RISC-V target.The proposal of
target_version
syntax can be found at the riscv-non-isa/riscv-c-api-doc#48 (which has landed), as modified by the proposed riscv-non-isa/riscv-c-api-doc#85 (which adds the priority syntax).target_version
attribute will trigger the function multi-versioning feature and act liketarget_clones
attribute. See #85786 for the implementation oftarget_clones
.