@@ -95,9 +95,12 @@ extern cl::opt<unsigned> MaxNumVTableAnnotations;
9595// global vars at all. When importing function we aren't interested if any
9696// instruction in it takes an address of any basic block, because instruction
9797// can only take an address of basic block located in the same function.
98+ // Set `RefLocalLinkageIFunc` to true if the analyzed value references a
99+ // local-linkage ifunc.
98100static bool findRefEdges (ModuleSummaryIndex &Index, const User *CurUser,
99101 SetVector<ValueInfo, std::vector<ValueInfo>> &RefEdges,
100- SmallPtrSet<const User *, 8 > &Visited) {
102+ SmallPtrSet<const User *, 8 > &Visited,
103+ bool &RefLocalLinkageIFunc) {
101104 bool HasBlockAddress = false ;
102105 SmallVector<const User *, 32 > Worklist;
103106 if (Visited.insert (CurUser).second )
@@ -119,8 +122,18 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
119122 // We have a reference to a global value. This should be added to
120123 // the reference set unless it is a callee. Callees are handled
121124 // specially by WriteFunction and are added to a separate list.
122- if (!(CB && CB->isCallee (&OI)))
125+ if (!(CB && CB->isCallee (&OI))) {
126+ // If an ifunc has local linkage, do not add it into ref edges, and
127+ // sets `RefLocalLinkageIFunc` to true. The referencer is not eligible
128+ // for import. An ifunc doesn't have summary and ThinLTO cannot
129+ // promote it; importing the referencer may cause linkage errors.
130+ if (auto *GI = dyn_cast_if_present<GlobalIFunc>(GV);
131+ GI && GI->hasLocalLinkage ()) {
132+ RefLocalLinkageIFunc = true ;
133+ continue ;
134+ }
123135 RefEdges.insert (Index.getOrInsertValueInfo (GV));
136+ }
124137 continue ;
125138 }
126139 if (Visited.insert (Operand).second )
@@ -313,7 +326,8 @@ static void computeFunctionSummary(
313326
314327 // Add personality function, prefix data and prologue data to function's ref
315328 // list.
316- findRefEdges (Index, &F, RefEdges, Visited);
329+ bool HasLocalIFuncCallOrRef = false ;
330+ findRefEdges (Index, &F, RefEdges, Visited, HasLocalIFuncCallOrRef);
317331 std::vector<const Instruction *> NonVolatileLoads;
318332 std::vector<const Instruction *> NonVolatileStores;
319333
@@ -326,7 +340,6 @@ static void computeFunctionSummary(
326340
327341 bool HasInlineAsmMaybeReferencingInternal = false ;
328342 bool HasIndirBranchToBlockAddress = false ;
329- bool HasIFuncCall = false ;
330343 bool HasUnknownCall = false ;
331344 bool MayThrow = false ;
332345 for (const BasicBlock &BB : F) {
@@ -372,11 +385,11 @@ static void computeFunctionSummary(
372385 // of calling it we should add GV to RefEdges directly.
373386 RefEdges.insert (Index.getOrInsertValueInfo (GV));
374387 else if (auto *U = dyn_cast<User>(Stored))
375- findRefEdges (Index, U, RefEdges, Visited);
388+ findRefEdges (Index, U, RefEdges, Visited, HasLocalIFuncCallOrRef );
376389 continue ;
377390 }
378391 }
379- findRefEdges (Index, &I, RefEdges, Visited);
392+ findRefEdges (Index, &I, RefEdges, Visited, HasLocalIFuncCallOrRef );
380393 const auto *CB = dyn_cast<CallBase>(&I);
381394 if (!CB) {
382395 if (I.mayThrow ())
@@ -450,7 +463,7 @@ static void computeFunctionSummary(
450463 // Non-local ifunc is not cloned and does not have the issue.
451464 if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
452465 if (GI->hasLocalLinkage ())
453- HasIFuncCall = true ;
466+ HasLocalIFuncCallOrRef = true ;
454467 // Skip inline assembly calls.
455468 if (CI && CI->isInlineAsm ())
456469 continue ;
@@ -555,7 +568,7 @@ static void computeFunctionSummary(
555568 SmallPtrSet<const User *, 8 > &Cache) {
556569 for (const auto *I : Instrs) {
557570 Cache.erase (I);
558- findRefEdges (Index, I, Edges, Cache);
571+ findRefEdges (Index, I, Edges, Cache, HasLocalIFuncCallOrRef );
559572 }
560573 };
561574
@@ -631,9 +644,9 @@ static void computeFunctionSummary(
631644#endif
632645
633646 bool NonRenamableLocal = isNonRenamableLocal (F);
634- bool NotEligibleForImport = NonRenamableLocal ||
635- HasInlineAsmMaybeReferencingInternal ||
636- HasIndirBranchToBlockAddress || HasIFuncCall ;
647+ bool NotEligibleForImport =
648+ NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
649+ HasIndirBranchToBlockAddress || HasLocalIFuncCallOrRef ;
637650 GlobalValueSummary::GVFlags Flags (
638651 F.getLinkage (), F.getVisibility (), NotEligibleForImport,
639652 /* Live = */ false , F.isDSOLocal (), F.canBeOmittedFromSymbolTable (),
@@ -787,7 +800,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
787800 SmallVectorImpl<MDNode *> &Types) {
788801 SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges;
789802 SmallPtrSet<const User *, 8 > Visited;
790- bool HasBlockAddress = findRefEdges (Index, &V, RefEdges, Visited);
803+ bool RefLocalIFunc = false ;
804+ bool HasBlockAddress =
805+ findRefEdges (Index, &V, RefEdges, Visited, RefLocalIFunc);
806+ const bool NotEligibleForImport = (HasBlockAddress || RefLocalIFunc);
791807 bool NonRenamableLocal = isNonRenamableLocal (V);
792808 GlobalValueSummary::GVFlags Flags (
793809 V.getLinkage (), V.getVisibility (), NonRenamableLocal,
@@ -821,7 +837,7 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
821837 RefEdges.takeVector ());
822838 if (NonRenamableLocal)
823839 CantBePromoted.insert (V.getGUID ());
824- if (HasBlockAddress )
840+ if (NotEligibleForImport )
825841 GVarSummary->setNotEligibleToImport ();
826842 if (!VTableFuncs.empty ())
827843 GVarSummary->setVTableFuncs (VTableFuncs);
0 commit comments