@@ -3712,7 +3712,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
37123712 // Forward declarations are emitted lazily on first use.
37133713 if (!FD->doesThisDeclarationHaveABody ()) {
37143714 if (!FD->doesDeclarationForceExternallyVisibleDefinition () &&
3715- !FD->isTargetVersionMultiVersion ())
3715+ (!FD->isMultiVersion () ||
3716+ !FD->getASTContext ().getTargetInfo ().getTriple ().isAArch64 ()))
37163717 return ;
37173718
37183719 StringRef MangledName = getMangledName (GD);
@@ -3994,10 +3995,11 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
39943995 auto *Spec = FD->getAttr <CPUSpecificAttr>();
39953996 for (unsigned I = 0 ; I < Spec->cpus_size (); ++I)
39963997 EmitGlobalFunctionDefinition (GD.getWithMultiVersionIndex (I), nullptr );
3997- } else if (FD->isTargetClonesMultiVersion ()) {
3998- auto *Clone = FD->getAttr <TargetClonesAttr>();
3999- for (unsigned I = 0 ; I < Clone->featuresStrs_size (); ++I)
4000- if (Clone->isFirstOfVersion (I))
3998+ } else if (auto *TC = FD->getAttr <TargetClonesAttr>()) {
3999+ for (unsigned I = 0 ; I < TC->featuresStrs_size (); ++I)
4000+ // AArch64 favors the default target version over the clone if any.
4001+ if ((!TC->isDefaultVersion (I) || !getTarget ().getTriple ().isAArch64 ()) &&
4002+ TC->isFirstOfVersion (I))
40014003 EmitGlobalFunctionDefinition (GD.getWithMultiVersionIndex (I), nullptr );
40024004 // Ensure that the resolver function is also emitted.
40034005 GetOrCreateMultiVersionResolver (GD);
@@ -4137,57 +4139,49 @@ void CodeGenModule::emitMultiVersionFunctions() {
41374139 };
41384140
41394141 bool HasDefaultDecl = !FD->isTargetVersionMultiVersion ();
4140- bool ShouldEmitResolver = !FD->isTargetVersionMultiVersion ();
4142+ bool ShouldEmitResolver =
4143+ !getContext ().getTargetInfo ().getTriple ().isAArch64 ();
41414144 SmallVector<CodeGenFunction::MultiVersionResolverOption, 10 > Options;
4142- if (FD->isTargetMultiVersion ()) {
4143- getContext ().forEachMultiversionedFunctionVersion (
4144- FD, [&](const FunctionDecl *CurFD) {
4145- llvm::SmallVector<StringRef, 8 > Feats;
4146- llvm::Function *Func = createFunction (CurFD);
41474145
4148- if (const auto *TA = CurFD->getAttr <TargetAttr>()) {
4149- TA->getAddedFeatures (Feats);
4150- Options.emplace_back (Func, TA->getArchitecture (), Feats);
4151- } else if (const auto *TVA = CurFD->getAttr <TargetVersionAttr>()) {
4152- bool HasDefaultDef = TVA->isDefaultVersion () &&
4153- CurFD->doesThisDeclarationHaveABody ();
4154- HasDefaultDecl |= TVA->isDefaultVersion ();
4155- ShouldEmitResolver |= (CurFD->isUsed () || HasDefaultDef);
4156- TVA->getFeatures (Feats);
4157- Options.emplace_back (Func, /* Architecture*/ " " , Feats);
4158- } else
4159- llvm_unreachable (" unexpected MultiVersionKind" );
4160- });
4161- } else if (const auto *TC = FD->getAttr <TargetClonesAttr>()) {
4162- for (unsigned I = 0 ; I < TC->featuresStrs_size (); ++I) {
4163- if (!TC->isFirstOfVersion (I))
4164- continue ;
4146+ getContext ().forEachMultiversionedFunctionVersion (
4147+ FD, [&](const FunctionDecl *CurFD) {
4148+ llvm::SmallVector<StringRef, 8 > Feats;
41654149
4166- llvm::Function *Func = createFunction (FD, I);
4167- StringRef Version = TC->getFeatureStr (I);
4168- StringRef Architecture;
4169- llvm::SmallVector<StringRef, 1 > Feature;
4170-
4171- if (getTarget ().getTriple ().isAArch64 ()) {
4172- if (Version != " default" ) {
4173- llvm::SmallVector<StringRef, 8 > VerFeats;
4174- Version.split (VerFeats, " +" );
4175- for (auto &CurFeat : VerFeats)
4176- Feature.push_back (CurFeat.trim ());
4177- }
4178- } else {
4179- if (Version.starts_with (" arch=" ))
4180- Architecture = Version.drop_front (sizeof (" arch=" ) - 1 );
4181- else if (Version != " default" )
4182- Feature.push_back (Version);
4183- }
4184-
4185- Options.emplace_back (Func, Architecture, Feature);
4186- }
4187- } else {
4188- assert (0 && " Expected a target or target_clones multiversion function" );
4189- continue ;
4190- }
4150+ if (const auto *TA = CurFD->getAttr <TargetAttr>()) {
4151+ TA->getAddedFeatures (Feats);
4152+ llvm::Function *Func = createFunction (CurFD);
4153+ Options.emplace_back (Func, TA->getArchitecture (), Feats);
4154+ } else if (const auto *TVA = CurFD->getAttr <TargetVersionAttr>()) {
4155+ bool HasDefaultDef = TVA->isDefaultVersion () &&
4156+ CurFD->doesThisDeclarationHaveABody ();
4157+ HasDefaultDecl |= TVA->isDefaultVersion ();
4158+ ShouldEmitResolver |= (CurFD->isUsed () || HasDefaultDef);
4159+ TVA->getFeatures (Feats);
4160+ llvm::Function *Func = createFunction (CurFD);
4161+ Options.emplace_back (Func, /* Architecture*/ " " , Feats);
4162+ } else if (const auto *TC = CurFD->getAttr <TargetClonesAttr>()) {
4163+ ShouldEmitResolver |= CurFD->doesThisDeclarationHaveABody ();
4164+ for (unsigned I = 0 ; I < TC->featuresStrs_size (); ++I) {
4165+ if (!TC->isFirstOfVersion (I))
4166+ continue ;
4167+
4168+ llvm::Function *Func = createFunction (CurFD, I);
4169+ StringRef Architecture;
4170+ Feats.clear ();
4171+ if (getTarget ().getTriple ().isAArch64 ())
4172+ TC->getFeatures (Feats, I);
4173+ else {
4174+ StringRef Version = TC->getFeatureStr (I);
4175+ if (Version.starts_with (" arch=" ))
4176+ Architecture = Version.drop_front (sizeof (" arch=" ) - 1 );
4177+ else if (Version != " default" )
4178+ Feats.push_back (Version);
4179+ }
4180+ Options.emplace_back (Func, Architecture, Feats);
4181+ }
4182+ } else
4183+ llvm_unreachable (" unexpected MultiVersionKind" );
4184+ });
41914185
41924186 if (!ShouldEmitResolver)
41934187 continue ;
@@ -4378,7 +4372,7 @@ void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) {
43784372 const auto *FD = cast<FunctionDecl>(GD.getDecl ());
43794373 assert (FD && " Not a FunctionDecl?" );
43804374
4381- if (FD->isTargetVersionMultiVersion ()) {
4375+ if (FD->isTargetVersionMultiVersion () || FD-> isTargetClonesMultiVersion () ) {
43824376 std::string MangledName =
43834377 getMangledNameImpl (*this , GD, FD, /* OmitMultiVersionMangling=*/ true );
43844378 if (!DeferredResolversToEmit.insert (MangledName).second )
@@ -4489,7 +4483,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
44894483
44904484 if (FD->isMultiVersion ()) {
44914485 UpdateMultiVersionNames (GD, FD, MangledName);
4492- if (FD->isTargetVersionMultiVersion () && !FD->isUsed ())
4486+ if (FD->getASTContext ().getTargetInfo ().getTriple ().isAArch64 () &&
4487+ !FD->isUsed ())
44934488 AddDeferredMultiVersionResolverToEmit (GD);
44944489 else if (!IsForDefinition)
44954490 return GetOrCreateMultiVersionResolver (GD);
0 commit comments