aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexandros Lamprineas <alexandros.lamprineas@arm.com>2024-12-19 12:06:46 +0000
committerGitHub <noreply@github.com>2024-12-19 12:06:46 +0000
commit6586c676b42aa9c7e78f9b1d419767a02793a70f (patch)
tree7eb67dad9e0445efa9fd4c843cb3f9cd13ed3882 /clang/lib
parenteace8269d9aeb67013d273735ec1be1002a6fac1 (diff)
downloadllvm-6586c676b42aa9c7e78f9b1d419767a02793a70f.zip
llvm-6586c676b42aa9c7e78f9b1d419767a02793a70f.tar.gz
llvm-6586c676b42aa9c7e78f9b1d419767a02793a70f.tar.bz2
[FMV][AArch64] Emit mangled default version if explicitly specified. (#120022)
Currently we need at least one more version other than the default to trigger FMV. However we would like a header file declaration __attribute__((target_version("default"))) void f(void); to guarantee that there will be f.default
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp47
2 files changed, 23 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 5ac3eef..c49f763 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4283,7 +4283,7 @@ void CodeGenModule::emitMultiVersionFunctions() {
getContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
llvm::SmallVector<StringRef, 8> Feats;
- bool IsDefined = CurFD->doesThisDeclarationHaveABody();
+ bool IsDefined = CurFD->getDefinition() != nullptr;
if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
assert(getTarget().getTriple().isX86() && "Unsupported target");
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 55e891e..4001c4d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11073,9 +11073,9 @@ bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) {
static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) {
const auto *TA = FD->getAttr<TargetAttr>();
const auto *TVA = FD->getAttr<TargetVersionAttr>();
- assert(
- (TA || TVA) &&
- "MultiVersion candidate requires a target or target_version attribute");
+
+ assert((TA || TVA) && "Expecting target or target_version attribute");
+
const TargetInfo &TargetInfo = S.Context.getTargetInfo();
enum ErrType { Feature = 0, Architecture = 1 };
@@ -11372,10 +11372,6 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD) {
// otherwise it is treated as a normal function.
if (TA && !TA->isDefaultVersion())
return false;
- // The target_version attribute only causes Multiversioning if this
- // declaration is NOT the default version.
- if (TVA && TVA->isDefaultVersion())
- return false;
if ((TA || TVA) && CheckMultiVersionValue(S, FD)) {
FD->setInvalidDecl();
@@ -11422,26 +11418,24 @@ static bool CheckDeclarationCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
LookupResult &Previous) {
assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+ const auto *NewTA = NewFD->getAttr<TargetAttr>();
+ const auto *OldTA = OldFD->getAttr<TargetAttr>();
+ const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
+ const auto *OldTVA = OldFD->getAttr<TargetVersionAttr>();
+
+ assert((NewTA || NewTVA) && "Excpecting target or target_version attribute");
+
// The definitions should be allowed in any order. If we have discovered
// a new target version and the preceeding was the default, then add the
// corresponding attribute to it.
patchDefaultTargetVersion(NewFD, OldFD);
- const auto *NewTA = NewFD->getAttr<TargetAttr>();
- const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
- const auto *OldTA = OldFD->getAttr<TargetAttr>();
-
// If the old decl is NOT MultiVersioned yet, and we don't cause that
// to change, this is a simple redeclaration.
if (NewTA && !NewTA->isDefaultVersion() &&
(!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr()))
return false;
- // The target_version attribute only causes Multiversioning if this
- // declaration is NOT the default version.
- if (NewTVA && NewTVA->isDefaultVersion())
- return false;
-
// Otherwise, this decl causes MultiVersioning.
if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, true,
NewTVA ? MultiVersionKind::TargetVersion
@@ -11456,7 +11450,8 @@ static bool CheckDeclarationCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
}
// If this is 'default', permit the forward declaration.
- if (NewTA && NewTA->isDefaultVersion() && !OldTA) {
+ if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
+ (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
Redeclaration = true;
OldDecl = OldFD;
OldFD->setIsMultiVersion();
@@ -11464,7 +11459,7 @@ static bool CheckDeclarationCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
return false;
}
- if (CheckMultiVersionValue(S, OldFD)) {
+ if ((OldTA || OldTVA) && CheckMultiVersionValue(S, OldFD)) {
S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here);
NewFD->setInvalidDecl();
return true;
@@ -11761,9 +11756,7 @@ static bool CheckMultiVersionAdditionalDecl(
// Else, this is simply a non-redecl case. Checking the 'value' is only
// necessary in the Target case, since The CPUSpecific/Dispatch cases are
// handled in the attribute adding step.
- if ((NewMVKind == MultiVersionKind::TargetVersion ||
- NewMVKind == MultiVersionKind::Target) &&
- CheckMultiVersionValue(S, NewFD)) {
+ if ((NewTA || NewTVA) && CheckMultiVersionValue(S, NewFD)) {
NewFD->setInvalidDecl();
return true;
}
@@ -11799,6 +11792,12 @@ static bool CheckMultiVersionAdditionalDecl(
static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
bool &Redeclaration, NamedDecl *&OldDecl,
LookupResult &Previous) {
+ const TargetInfo &TI = S.getASTContext().getTargetInfo();
+
+ // Check if FMV is disabled.
+ if (TI.getTriple().isAArch64() && !TI.hasFeature("fmv"))
+ return false;
+
const auto *NewTA = NewFD->getAttr<TargetAttr>();
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
const auto *NewCPUDisp = NewFD->getAttr<CPUDispatchAttr>();
@@ -11821,14 +11820,12 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
return false;
}
- const llvm::Triple &T = S.getASTContext().getTargetInfo().getTriple();
-
// Target attribute on AArch64 is not used for multiversioning
- if (NewTA && T.isAArch64())
+ if (NewTA && TI.getTriple().isAArch64())
return false;
// Target attribute on RISCV is not used for multiversioning
- if (NewTA && T.isRISCV())
+ if (NewTA && TI.getTriple().isRISCV())
return false;
if (!OldDecl || !OldDecl->getAsFunction() ||