@@ -95,9 +95,12 @@ extern cl::opt<unsigned> MaxNumVTableAnnotations;
95
95
// global vars at all. When importing function we aren't interested if any
96
96
// instruction in it takes an address of any basic block, because instruction
97
97
// 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.
98
100
static bool findRefEdges (ModuleSummaryIndex &Index, const User *CurUser,
99
101
SetVector<ValueInfo, std::vector<ValueInfo>> &RefEdges,
100
- SmallPtrSet<const User *, 8 > &Visited) {
102
+ SmallPtrSet<const User *, 8 > &Visited,
103
+ bool &RefLocalLinkageIFunc) {
101
104
bool HasBlockAddress = false ;
102
105
SmallVector<const User *, 32 > Worklist;
103
106
if (Visited.insert (CurUser).second )
@@ -119,8 +122,18 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
119
122
// We have a reference to a global value. This should be added to
120
123
// the reference set unless it is a callee. Callees are handled
121
124
// 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
+ }
123
135
RefEdges.insert (Index.getOrInsertValueInfo (GV));
136
+ }
124
137
continue ;
125
138
}
126
139
if (Visited.insert (Operand).second )
@@ -313,7 +326,8 @@ static void computeFunctionSummary(
313
326
314
327
// Add personality function, prefix data and prologue data to function's ref
315
328
// list.
316
- findRefEdges (Index, &F, RefEdges, Visited);
329
+ bool HasLocalIFuncCallOrRef = false ;
330
+ findRefEdges (Index, &F, RefEdges, Visited, HasLocalIFuncCallOrRef);
317
331
std::vector<const Instruction *> NonVolatileLoads;
318
332
std::vector<const Instruction *> NonVolatileStores;
319
333
@@ -326,7 +340,6 @@ static void computeFunctionSummary(
326
340
327
341
bool HasInlineAsmMaybeReferencingInternal = false ;
328
342
bool HasIndirBranchToBlockAddress = false ;
329
- bool HasIFuncCall = false ;
330
343
bool HasUnknownCall = false ;
331
344
bool MayThrow = false ;
332
345
for (const BasicBlock &BB : F) {
@@ -372,11 +385,11 @@ static void computeFunctionSummary(
372
385
// of calling it we should add GV to RefEdges directly.
373
386
RefEdges.insert (Index.getOrInsertValueInfo (GV));
374
387
else if (auto *U = dyn_cast<User>(Stored))
375
- findRefEdges (Index, U, RefEdges, Visited);
388
+ findRefEdges (Index, U, RefEdges, Visited, HasLocalIFuncCallOrRef );
376
389
continue ;
377
390
}
378
391
}
379
- findRefEdges (Index, &I, RefEdges, Visited);
392
+ findRefEdges (Index, &I, RefEdges, Visited, HasLocalIFuncCallOrRef );
380
393
const auto *CB = dyn_cast<CallBase>(&I);
381
394
if (!CB) {
382
395
if (I.mayThrow ())
@@ -450,7 +463,7 @@ static void computeFunctionSummary(
450
463
// Non-local ifunc is not cloned and does not have the issue.
451
464
if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
452
465
if (GI->hasLocalLinkage ())
453
- HasIFuncCall = true ;
466
+ HasLocalIFuncCallOrRef = true ;
454
467
// Skip inline assembly calls.
455
468
if (CI && CI->isInlineAsm ())
456
469
continue ;
@@ -555,7 +568,7 @@ static void computeFunctionSummary(
555
568
SmallPtrSet<const User *, 8 > &Cache) {
556
569
for (const auto *I : Instrs) {
557
570
Cache.erase (I);
558
- findRefEdges (Index, I, Edges, Cache);
571
+ findRefEdges (Index, I, Edges, Cache, HasLocalIFuncCallOrRef );
559
572
}
560
573
};
561
574
@@ -631,9 +644,9 @@ static void computeFunctionSummary(
631
644
#endif
632
645
633
646
bool NonRenamableLocal = isNonRenamableLocal (F);
634
- bool NotEligibleForImport = NonRenamableLocal ||
635
- HasInlineAsmMaybeReferencingInternal ||
636
- HasIndirBranchToBlockAddress || HasIFuncCall ;
647
+ bool NotEligibleForImport =
648
+ NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
649
+ HasIndirBranchToBlockAddress || HasLocalIFuncCallOrRef ;
637
650
GlobalValueSummary::GVFlags Flags (
638
651
F.getLinkage (), F.getVisibility (), NotEligibleForImport,
639
652
/* Live = */ false , F.isDSOLocal (), F.canBeOmittedFromSymbolTable (),
@@ -787,7 +800,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
787
800
SmallVectorImpl<MDNode *> &Types) {
788
801
SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges;
789
802
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);
791
807
bool NonRenamableLocal = isNonRenamableLocal (V);
792
808
GlobalValueSummary::GVFlags Flags (
793
809
V.getLinkage (), V.getVisibility (), NonRenamableLocal,
@@ -821,7 +837,7 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
821
837
RefEdges.takeVector ());
822
838
if (NonRenamableLocal)
823
839
CantBePromoted.insert (V.getGUID ());
824
- if (HasBlockAddress )
840
+ if (NotEligibleForImport )
825
841
GVarSummary->setNotEligibleToImport ();
826
842
if (!VTableFuncs.empty ())
827
843
GVarSummary->setVTableFuncs (VTableFuncs);
0 commit comments