diff options
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 13 |
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()); |