diff options
author | Alexandros Lamprineas <alexandros.lamprineas@arm.com> | 2024-12-19 12:06:46 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-19 12:06:46 +0000 |
commit | 6586c676b42aa9c7e78f9b1d419767a02793a70f (patch) | |
tree | 7eb67dad9e0445efa9fd4c843cb3f9cd13ed3882 /clang/lib | |
parent | eace8269d9aeb67013d273735ec1be1002a6fac1 (diff) | |
download | llvm-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.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 47 |
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() || |