@@ -3384,7 +3384,8 @@ void PPCAIXAsmPrinter::emitModuleCommandLines(Module &M) {
33843384 OutStreamer->emitXCOFFCInfoSym (" .GCC.command.line" , RSOS.str ());
33853385}
33863386
3387- static bool TOCRestoreNeeded (const GlobalIFunc &GI) {
3387+
3388+ static bool TOCRestoreNeededForCallToImplementation (const GlobalIFunc &GI) {
33883389 auto IsLocalFunc = [&](const Value *V) {
33893390 if (!isa<Function>(V))
33903391 return false ;
@@ -3458,10 +3459,11 @@ static bool TOCRestoreNeeded(const GlobalIFunc &GI) {
34583459 * .vbyte 4, 0
34593460 * .csect .foo[PR],5
34603461 * .ref ifunc_sec.foo[RW]
3461- * lwz 12, L..C3(2)
3462- * lwz 12, 0(12)
3462+ * ld 12, L..foo_desc(2) # load foo's descriptor address
3463+ * ld 11, 16(12) # load the env pointer if target might be a non-C/C++ function, otherwise this load is omitted
3464+ * ld 12, 0(12) # load foo.addr
34633465 * mtctr 12
3464- * bctr
3466+ * bctr # branch to CR without setting LR so that callee returns to the caller of .foo
34653467 * # -- End function
34663468 */
34673469void PPCAIXAsmPrinter::emitGlobalIFunc (Module &M, const GlobalIFunc &GI) {
@@ -3536,15 +3538,16 @@ void PPCAIXAsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
35363538 // ^^^^^^ TEMPORARY ^^^^^
35373539
35383540 // generate the code for .foo now:
3539- if (TOCRestoreNeeded (GI)) {
3541+ if (TOCRestoreNeededForCallToImplementation (GI)) {
35403542 reportFatalUsageError (
3541- " unimplmented : TOC register save/restore needed for function " +
3543+ " unimplemented : TOC register save/restore needed for function " +
35423544 Twine (GI.getName ()) +
3543- " , check if -mllvm -ifunc-local=... applies to your case" );
3545+ " , because couldn't prove all candidates are static or hidden/protected"
3546+ " visibility definitions" );
35443547 return ;
35453548 }
35463549
3547- // lwz 12, L..C3 (2)
3550+ // lwz 12, L..foo_desc (2)
35483551 auto FnDescTOCEntryType = getTOCEntryTypeForLinkage (GI.getLinkage ());
35493552 auto *FnDescTOCEntrySym =
35503553 lookUpOrCreateTOCEntry (CurrentFnDescSym, FnDescTOCEntryType);
@@ -3556,7 +3559,12 @@ void PPCAIXAsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
35563559 .addExpr (Exp)
35573560 .addReg (PPC::X2),
35583561 *Subtarget);
3559-
3562+ // lwz 11, 8(12)
3563+ OutStreamer->emitInstruction (MCInstBuilder (IsPPC64 ? PPC::LD : PPC::LWZ)
3564+ .addReg (PPC::X11)
3565+ .addImm (IsPPC64 ? 16 : 8 )
3566+ .addReg (PPC::X12),
3567+ *Subtarget);
35603568 // lwz 12, 0(12)
35613569 OutStreamer->emitInstruction (MCInstBuilder (IsPPC64 ? PPC::LD : PPC::LWZ)
35623570 .addReg (PPC::X12)
0 commit comments