-
Notifications
You must be signed in to change notification settings - Fork 14k
[Clang] Fix linker error for function multiversioning #71706
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
Changes from 3 commits
534fad7
362f0cb
ab1f8a1
763221c
af600cb
e6529cd
c6cc8be
fcc6db8
45d849c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4114,8 +4114,26 @@ void CodeGenModule::emitMultiVersionFunctions() { | |
} | ||
|
||
llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); | ||
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) | ||
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) { | ||
ResolverConstant = IFunc->getResolver(); | ||
// In Aarch64, default versions of multiversioned functions are mangled to | ||
// their 'normal' assembly name. This deviates from other targets which | ||
// append a '.default' string. As a result we need to continue appending | ||
// .ifunc in Aarch64. | ||
// FIXME: Should Aarch64 mangling for 'default' multiversion function and | ||
// in turn ifunc function match that of other targets? | ||
Comment on lines
+4183
to
+4188
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DanielKristofKiss, please ensure this comment and FIXME is addressed/removed by your follow up patch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have been meaning to file an issue about this. Not using a different mangling means you always get the default version when referencing a multi-versioned function outside of the TU. Consider e.g:
@rsandifo-arm brought up a similar case on x86:
If we fix this, we should definitely make sure both the ACLE folks, and GCC are on board, and that the fix makes sense in the context of other targets. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://gcc.gnu.org/wiki/FunctionMultiVersioning says "The only exception to this is the default version tagged with target attribute string "default". The default version retains the original assembler name and is not changed" Looks like this was intentional for some reason. It is interesting that GCC changed mangling rules for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since I suspect the I just discovered that gcc doesn't support the |
||
if (FD->isTargetClonesMultiVersion() && | ||
!getTarget().getTriple().isAArch64()) { | ||
const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); | ||
llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); | ||
std::string MangledName = getMangledNameImpl( | ||
*this, GD, FD, /*OmitMultiVersionMangling=*/true); | ||
auto *Alias = llvm::GlobalAlias::create( | ||
DeclTy, 0, getMultiversionLinkage(*this, GD), | ||
MangledName + ".ifunc", IFunc, &getModule()); | ||
SetCommonAttributes(FD, Alias); | ||
} | ||
elizabethandrews marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant); | ||
|
||
ResolverFunc->setLinkage(getMultiversionLinkage(*this, GD)); | ||
|
@@ -4282,10 +4300,19 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { | |
// Holds the name of the resolver, in ifunc mode this is the ifunc (which has | ||
// a separate resolver). | ||
std::string ResolverName = MangledName; | ||
if (getTarget().supportsIFunc()) | ||
ResolverName += ".ifunc"; | ||
else if (FD->isTargetMultiVersion()) | ||
if (getTarget().supportsIFunc()) { | ||
// In Aarch64, default versions of multiversioned functions are mangled to | ||
// their 'normal' assembly name. This deviates from other targets which | ||
// append a '.default' string. As a result we need to continue appending | ||
// .ifunc in Aarch64. | ||
// FIXME: Should Aarch64 mangling for 'default' multiversion function and | ||
// in turn ifunc function match that of other targets? | ||
Comment on lines
+4371
to
+4376
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DanielKristofKiss, please ensure this comment and FIXME is addressed/removed by your follow up patch. |
||
if (!FD->isTargetClonesMultiVersion() || | ||
getTarget().getTriple().isAArch64()) | ||
ResolverName += ".ifunc"; | ||
} else if (FD->isTargetMultiVersion()) { | ||
ResolverName += ".resolver"; | ||
} | ||
|
||
// If the resolver has already been created, just return it. | ||
if (llvm::GlobalValue *ResolverGV = GetGlobalValue(ResolverName)) | ||
|
Uh oh!
There was an error while loading. Please reload this page.