-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
534fad7
[Clang] Fix linker error for function multiversioning
elizabethandrews 362f0cb
Use getMultiversionLinkage() for Linkage when generating alias
elizabethandrews ab1f8a1
Merge remote-tracking branch 'upstream/main' into ifunc
elizabethandrews 763221c
Apply review comments
elizabethandrews af600cb
Merge remote-tracking branch 'upstream/main' into ifunc
elizabethandrews e6529cd
Merge remote-tracking branch 'upstream/main' into ifunc
elizabethandrews c6cc8be
Merge remote-tracking branch 'upstream/main' into ifunc
elizabethandrews fcc6db8
Apply review comments
elizabethandrews 45d849c
Update clang/include/clang/Basic/AttrDocs.td
elizabethandrews File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4178,8 +4178,29 @@ 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? | ||
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); | ||
// In prior versions of Clang, the mangling for ifuncs incorrectly | ||
// included an .ifunc suffix. This alias is generated for backward | ||
// compatibility. It is deprecated, and may be removed in the future. | ||
auto *Alias = llvm::GlobalAlias::create( | ||
DeclTy, 0, getMultiversionLinkage(*this, GD), | ||
MangledName + ".ifunc", IFunc, &getModule()); | ||
SetCommonAttributes(FD, Alias); | ||
} | ||
} | ||
llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant); | ||
|
||
ResolverFunc->setLinkage(getMultiversionLinkage(*this, GD)); | ||
|
@@ -4346,10 +4367,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)) | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
@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 comment
The 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 comment
The 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
target_clones
attribute though. The default versions do have a.default
suffixThere 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.
Since
target_version
is new, I think it is reasonable to change its behavior (via a different github PR).I suspect the
target
behavior is an artifact of how the multiversion function features evolved. My best guess is that the original implementation didn't support an indirect function facility that enabled dynamic resolution from outside a defining TU. Perhaps that was part of the motivation for addingtarget_clones
.I just discovered that gcc doesn't support the
target
attribute when compiling for C. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108964. I had been under the impression that it just didn't support overloading on thetarget
attribute (but that the attribute still affected code generation). Interesting that no warning is given for an ignored attribute. Here is the example from the doc Elizabeth linked compiling as C. https://godbolt.org/z/asfrhG51G.