aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 775bb95..a88622e 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -305,6 +305,7 @@ static void computeFunctionSummary(
bool HasInlineAsmMaybeReferencingInternal = false;
bool HasIndirBranchToBlockAddress = false;
+ bool HasIFuncCall = false;
bool HasUnknownCall = false;
bool MayThrow = false;
for (const BasicBlock &BB : F) {
@@ -417,6 +418,16 @@ static void computeFunctionSummary(
}
} else {
HasUnknownCall = true;
+ // If F is imported, a local linkage ifunc (e.g. target_clones on a
+ // static function) called by F will be cloned. Since summaries don't
+ // track ifunc, we do not know implementation functions referenced by
+ // the ifunc resolver need to be promoted in the exporter, and we will
+ // get linker errors due to cloned declarations for implementation
+ // functions. As a simple fix, just mark F as not eligible for import.
+ // Non-local ifunc is not cloned and does not have the issue.
+ if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
+ if (GI->hasLocalLinkage())
+ HasIFuncCall = true;
// Skip inline assembly calls.
if (CI && CI->isInlineAsm())
continue;
@@ -599,7 +610,7 @@ static void computeFunctionSummary(
bool NonRenamableLocal = isNonRenamableLocal(F);
bool NotEligibleForImport = NonRenamableLocal ||
HasInlineAsmMaybeReferencingInternal ||
- HasIndirBranchToBlockAddress;
+ HasIndirBranchToBlockAddress || HasIFuncCall;
GlobalValueSummary::GVFlags Flags(
F.getLinkage(), F.getVisibility(), NotEligibleForImport,
/* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable());