diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -1661,10 +1661,12 @@ else return false; } else { - // Build direct call with NOP for TOC restore. - // FIXME: We can and should optimize away the NOP for local calls. - MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(PPC::BL8_NOP)); + // Build direct call. + bool ShareTOCBase = !Subtarget->isUsingPCRelativeCalls() && + Subtarget->getTargetLowering()->callsShareTOCBase( + &FuncInfo.MF->getFunction(), GV); + unsigned CallOP = ShareTOCBase ? PPC::BL8 : PPC::BL8_NOP; + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOP)); // Add callee. MIB.addGlobalAddress(GV); } diff --git a/llvm/test/CodeGen/PowerPC/pr55607.ll b/llvm/test/CodeGen/PowerPC/pr55607.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr55607.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr -fast-isel \ +; RUN: -mtriple=powerpc64le-unknown-unknown < %s | FileCheck %s + +define dso_local signext i32 @callee() { +; CHECK-LABEL: callee: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: li r3, 0 +; CHECK-NEXT: blr +entry: + ret i32 0 +} + +define dso_local signext i32 @foo() nounwind { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr r0 +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r0, 16(r1) +; CHECK-NEXT: stdu r1, -112(r1) +; CHECK-NEXT: bl callee +; CHECK-NEXT: mr r30, r3 +; CHECK-NEXT: bl callee2 +; CHECK-NEXT: nop +; CHECK-NEXT: add r3, r30, r3 +; CHECK-NEXT: extsw r3, r3 +; CHECK-NEXT: addi r1, r1, 112 +; CHECK-NEXT: ld r0, 16(r1) +; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload +; CHECK-NEXT: mtlr r0 +; CHECK-NEXT: blr +entry: + %call = call signext i32 @callee() + %call1 = call signext i32 @callee2() + %add = add nsw i32 %call, %call1 + ret i32 %add +} + +declare signext i32 @callee2()