Skip to content

Commit 1354a03

Browse files
[PowerPC][Future] Implement PC Relative Tail Calls
Tail Calls were initially disabled for PC Relative code because it was not safe to make certain assumptions about the tail calls (namely that all compiled functions no longer used the TOC pointer in R2). However, once all of the TOC pointer references have been removed it is safe to tail call everything that was tail called prior to the PC relative additions as well as a number of new cases. For example, it is now possible to tail call indirect functions as there is no need to save and restore the TOC pointer for indirect functions if the caller is marked as may clobber R2 (st_other=1). For the same reason it is now also possible to tail call functions that are external. Differential Revision: https://reviews.llvm.org/D77788
1 parent bd60b29 commit 1354a03

File tree

9 files changed

+341
-152
lines changed

9 files changed

+341
-152
lines changed

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,13 +1537,14 @@ void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
15371537
// 3) A function does not use the TOC pointer R2 but does have calls.
15381538
// In this case st_other=1 since we do not know whether or not any
15391539
// of the callees clobber R2. This case is dealt with in this else if
1540-
// block.
1540+
// block. Tail calls are considered calls and the st_other should also
1541+
// be set to 1 in that case as well.
15411542
// 4) The function does not use the TOC pointer but R2 is used inside
15421543
// the function. In this case st_other=1 once again.
15431544
// 5) This function uses inline asm. We mark R2 as reserved if the function
1544-
// has inline asm so we have to assume that it may be used.
1545-
if (MF->getFrameInfo().hasCalls() || MF->hasInlineAsm() ||
1546-
(!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {
1545+
// has inline asm as we have to assume that it may be used.
1546+
if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
1547+
MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {
15471548
PPCTargetStreamer *TS =
15481549
static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
15491550
if (TS)

llvm/lib/Target/PowerPC/PPCFrameLowering.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,13 +1674,25 @@ void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
16741674
DebugLoc dl = MBBI->getDebugLoc();
16751675
const PPCInstrInfo &TII = *Subtarget.getInstrInfo();
16761676

1677-
// Create branch instruction for pseudo tail call return instruction
1677+
// Create branch instruction for pseudo tail call return instruction.
1678+
// The TCRETURNdi variants are direct calls. Valid targets for those are
1679+
// MO_GlobalAddress operands as well as MO_ExternalSymbol with PC-Rel
1680+
// since we can tail call external functions with PC-Rel (i.e. we don't need
1681+
// to worry about different TOC pointers). Some of the external functions will
1682+
// be MO_GlobalAddress while others like memcpy for example, are going to
1683+
// be MO_ExternalSymbol.
16781684
unsigned RetOpcode = MBBI->getOpcode();
16791685
if (RetOpcode == PPC::TCRETURNdi) {
16801686
MBBI = MBB.getLastNonDebugInstr();
16811687
MachineOperand &JumpTarget = MBBI->getOperand(0);
1682-
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
1683-
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1688+
if (JumpTarget.isGlobal())
1689+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
1690+
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1691+
else if (JumpTarget.isSymbol())
1692+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
1693+
addExternalSymbol(JumpTarget.getSymbolName());
1694+
else
1695+
llvm_unreachable("Expecting Global or External Symbol");
16841696
} else if (RetOpcode == PPC::TCRETURNri) {
16851697
MBBI = MBB.getLastNonDebugInstr();
16861698
assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
@@ -1692,8 +1704,14 @@ void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
16921704
} else if (RetOpcode == PPC::TCRETURNdi8) {
16931705
MBBI = MBB.getLastNonDebugInstr();
16941706
MachineOperand &JumpTarget = MBBI->getOperand(0);
1695-
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
1696-
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1707+
if (JumpTarget.isGlobal())
1708+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
1709+
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
1710+
else if (JumpTarget.isSymbol())
1711+
BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
1712+
addExternalSymbol(JumpTarget.getSymbolName());
1713+
else
1714+
llvm_unreachable("Expecting Global or External Symbol");
16971715
} else if (RetOpcode == PPC::TCRETURNri8) {
16981716
MBBI = MBB.getLastNonDebugInstr();
16991717
assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4780,16 +4780,6 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
47804780
const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
47814781
bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
47824782

4783-
// FIXME: Tail calls are currently disabled when using PC Relative addressing.
4784-
// The issue is that PC Relative is only partially implemented and so there
4785-
// is currently a mix of functions that require the TOC and functions that do
4786-
// not require it. If we have A calls B calls C and both A and B require the
4787-
// TOC and C does not and is marked as clobbering R2 then it is not safe for
4788-
// B to tail call C. Since we do not have the information of whether or not
4789-
// a funciton needs to use the TOC here in this function we need to be
4790-
// conservatively safe and disable all tail calls for now.
4791-
if (Subtarget.isUsingPCRelativeCalls()) return false;
4792-
47934783
if (DisableSCO && !TailCallOpt) return false;
47944784

47954785
// Variadic argument functions are not supported.
@@ -4829,15 +4819,22 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
48294819
needStackSlotPassParameters(Subtarget, Outs))
48304820
return false;
48314821

4832-
// No TCO/SCO on indirect call because Caller have to restore its TOC
4833-
if (!isFunctionGlobalAddress(Callee) &&
4834-
!isa<ExternalSymbolSDNode>(Callee))
4822+
// All variants of 64-bit ELF ABIs without PC-Relative addressing require that
4823+
// the caller and callee share the same TOC for TCO/SCO. If the caller and
4824+
// callee potentially have different TOC bases then we cannot tail call since
4825+
// we need to restore the TOC pointer after the call.
4826+
// ref: https://bugzilla.mozilla.org/show_bug.cgi?id=973977
4827+
// We cannot guarantee this for indirect calls or calls to external functions.
4828+
// When PC-Relative addressing is used, the concept of the TOC is no longer
4829+
// applicable so this check is not required.
4830+
// Check first for indirect calls.
4831+
if (!Subtarget.isUsingPCRelativeCalls() &&
4832+
!isFunctionGlobalAddress(Callee) && !isa<ExternalSymbolSDNode>(Callee))
48354833
return false;
48364834

4837-
// If the caller and callee potentially have different TOC bases then we
4838-
// cannot tail call since we need to restore the TOC pointer after the call.
4839-
// ref: https://bugzilla.mozilla.org/show_bug.cgi?id=973977
4840-
if (!callsShareTOCBase(&Caller, Callee, getTargetMachine()))
4835+
// Check if we share the TOC base.
4836+
if (!Subtarget.isUsingPCRelativeCalls() &&
4837+
!callsShareTOCBase(&Caller, Callee, getTargetMachine()))
48414838
return false;
48424839

48434840
// TCO allows altering callee ABI, so we don't have to check further.
@@ -4849,11 +4846,14 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
48494846
// If callee use the same argument list that caller is using, then we can
48504847
// apply SCO on this case. If it is not, then we need to check if callee needs
48514848
// stack for passing arguments.
4852-
assert(CB && "Expected to have a CallBase!");
4853-
if (!hasSameArgumentList(&Caller, *CB) &&
4854-
needStackSlotPassParameters(Subtarget, Outs)) {
4849+
// PC Relative tail calls may not have a CallBase.
4850+
// If there is no CallBase we cannot verify if we have the same argument
4851+
// list so assume that we don't have the same argument list.
4852+
if (CB && !hasSameArgumentList(&Caller, *CB) &&
4853+
needStackSlotPassParameters(Subtarget, Outs))
4854+
return false;
4855+
else if (!CB && needStackSlotPassParameters(Subtarget, Outs))
48554856
return false;
4856-
}
48574857

48584858
return true;
48594859
}
@@ -5534,13 +5534,18 @@ SDValue PPCTargetLowering::FinishCall(
55345534

55355535
// Emit tail call.
55365536
if (CFlags.IsTailCall) {
5537+
// Indirect tail call when using PC Relative calls do not have the same
5538+
// constraints.
55375539
assert(((Callee.getOpcode() == ISD::Register &&
55385540
cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
55395541
Callee.getOpcode() == ISD::TargetExternalSymbol ||
55405542
Callee.getOpcode() == ISD::TargetGlobalAddress ||
5541-
isa<ConstantSDNode>(Callee)) &&
5542-
"Expecting a global address, external symbol, absolute value or "
5543-
"register");
5543+
isa<ConstantSDNode>(Callee) ||
5544+
(CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5545+
"Expecting a global address, external symbol, absolute value, "
5546+
"register or an indirect tail call when PC Relative calls are "
5547+
"used.");
5548+
// PC Relative calls also use TC_RETURN as the way to mark tail calls.
55445549
assert(CallOpc == PPCISD::TC_RETURN &&
55455550
"Unexpected call opcode for a tail call.");
55465551
DAG.getMachineFunction().getFrameInfo().setHasTailCall();
@@ -5598,17 +5603,19 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
55985603
if (!getTargetMachine().Options.GuaranteedTailCallOpt)
55995604
++NumSiblingCalls;
56005605

5601-
assert(isa<GlobalAddressSDNode>(Callee) &&
5606+
// PC Relative calls no longer guarantee that the callee is a Global
5607+
// Address Node. The callee could be an indirect tail call in which
5608+
// case the SDValue for the callee could be a load (to load the address
5609+
// of a function pointer) or it may be a register copy (to move the
5610+
// address of the callee from a function parameter into a virtual
5611+
// register). It may also be an ExternalSymbolSDNode (ex memcopy).
5612+
assert((Subtarget.isUsingPCRelativeCalls() ||
5613+
isa<GlobalAddressSDNode>(Callee)) &&
56025614
"Callee should be an llvm::Function object.");
5603-
LLVM_DEBUG(
5604-
const GlobalValue *GV =
5605-
cast<GlobalAddressSDNode>(Callee)->getGlobal();
5606-
const unsigned Width =
5607-
80 - strlen("TCO caller: ") - strlen(", callee linkage: 0, 0");
5608-
dbgs() << "TCO caller: "
5609-
<< left_justify(DAG.getMachineFunction().getName(), Width)
5610-
<< ", callee linkage: " << GV->getVisibility() << ", "
5611-
<< GV->getLinkage() << "\n");
5615+
5616+
LLVM_DEBUG(dbgs() << "TCO caller: " << DAG.getMachineFunction().getName()
5617+
<< "\nTCO callee: ");
5618+
LLVM_DEBUG(Callee.dump());
56125619
}
56135620
}
56145621

llvm/lib/Target/PowerPC/PPCMCInstLower.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,22 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
8686
RefKind = MCSymbolRefExpr::VK_PPC_GOT_PCREL;
8787

8888
const MachineInstr *MI = MO.getParent();
89-
90-
if (MI->getOpcode() == PPC::BL8_NOTOC)
91-
RefKind = MCSymbolRefExpr::VK_PPC_NOTOC;
92-
9389
const MachineFunction *MF = MI->getMF();
9490
const Module *M = MF->getFunction().getParent();
9591
const PPCSubtarget *Subtarget = &(MF->getSubtarget<PPCSubtarget>());
9692
const TargetMachine &TM = Printer.TM;
93+
94+
unsigned MIOpcode = MI->getOpcode();
95+
assert((Subtarget->isUsingPCRelativeCalls() || MIOpcode != PPC::BL8_NOTOC) &&
96+
"BL8_NOTOC is only valid when using PC Relative Calls.");
97+
if (Subtarget->isUsingPCRelativeCalls()) {
98+
if (MIOpcode == PPC::TAILB || MIOpcode == PPC::TAILB8 ||
99+
MIOpcode == PPC::TCRETURNdi || MIOpcode == PPC::TCRETURNdi8 ||
100+
MIOpcode == PPC::BL8_NOTOC) {
101+
RefKind = MCSymbolRefExpr::VK_PPC_NOTOC;
102+
}
103+
}
104+
97105
const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);
98106
// If -msecure-plt -fPIC, add 32768 to symbol.
99107
if (Subtarget->isSecurePlt() && TM.isPositionIndependent() &&

llvm/test/CodeGen/PowerPC/pcrel-call-linkage-simple.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77

88

99
; CHECK-S-LABEL: caller
10-
; CHECK-S: bl callee@notoc
11-
; CHECK-S: blr
10+
; CHECK-S: b callee@notoc
1211

1312
; CHECK-O-LABEL: caller
14-
; CHECK-O: bl
13+
; CHECK-O: b
1514
; CHECK-O-NEXT: R_PPC64_REL24_NOTOC callee
16-
; CHECK-O: blr
1715
define dso_local signext i32 @caller() local_unnamed_addr {
1816
entry:
1917
%call = tail call signext i32 bitcast (i32 (...)* @callee to i32 ()*)()
@@ -25,13 +23,11 @@ declare signext i32 @callee(...) local_unnamed_addr
2523

2624
; Some calls can be considered Extrnal Symbols.
2725
; CHECK-S-LABEL: ExternalSymbol
28-
; CHECK-S: bl memcpy@notoc
29-
; CHECK-S: blr
26+
; CHECK-S: b memcpy@notoc
3027

3128
; CHECK-O-LABEL: ExternalSymbol
32-
; CHECK-O: bl
29+
; CHECK-O: b
3330
; CHECK-O-NEXT: R_PPC64_REL24_NOTOC memcpy
34-
; CHECK-O: blr
3531
define dso_local void @ExternalSymbol(i8* nocapture %out, i8* nocapture readonly %in, i64 %num) local_unnamed_addr {
3632
entry:
3733
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %out, i8* align 1 %in, i64 %num, i1 false)

llvm/test/CodeGen/PowerPC/pcrel-call-linkage-with-calls.ll

Lines changed: 13 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,10 @@ define dso_local signext i32 @TailCallLocal1(i32 signext %a) local_unnamed_addr
193193
; CHECK-ALL-LABEL: TailCallLocal1:
194194
; CHECK-S: .localentry TailCallLocal1
195195
; CHECK-S: # %bb.0: # %entry
196-
; CHECK-S-NEXT: mflr r0
197-
; CHECK-S-NEXT: std r0, 16(r1)
198-
; CHECK-S-NEXT: stdu r1, -32(r1)
199-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
200-
; CHECK-S-NEXT: .cfi_offset lr, 16
201-
; CHECK-S-NEXT: plwz r4, globalVar@PCREL(0), 1
196+
; CHECK-S: plwz r4, globalVar@PCREL(0), 1
202197
; CHECK-S-NEXT: add r3, r4, r3
203198
; CHECK-S-NEXT: extsw r3, r3
204-
; CHECK-S-NEXT: bl localCall@notoc
205-
; CHECK-S-NEXT: addi r1, r1, 32
206-
; CHECK-S-NEXT: ld r0, 16(r1)
207-
; CHECK-S-NEXT: mtlr r0
208-
; CHECK-S-NEXT: blr
199+
; CHECK-S-NEXT: b localCall@notoc
209200
entry:
210201
%0 = load i32, i32* @globalVar, align 4
211202
%add = add nsw i32 %0, %a
@@ -217,20 +208,11 @@ define dso_local signext i32 @TailCallLocal2(i32 signext %a) local_unnamed_addr
217208
; CHECK-ALL-LABEL: TailCallLocal2:
218209
; CHECK-S: .localentry TailCallLocal2
219210
; CHECK-S: # %bb.0: # %entry
220-
; CHECK-S-NEXT: mflr r0
221-
; CHECK-S-NEXT: std r0, 16(r1)
222-
; CHECK-S-NEXT: stdu r1, -32(r1)
223-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
224-
; CHECK-S-NEXT: .cfi_offset lr, 16
225-
; CHECK-S-NEXT: pld r4, externGlobalVar@got@pcrel(0), 1
211+
; CHECK-S: pld r4, externGlobalVar@got@pcrel(0), 1
226212
; CHECK-S-NEXT: lwz r4, 0(r4)
227213
; CHECK-S-NEXT: add r3, r4, r3
228214
; CHECK-S-NEXT: extsw r3, r3
229-
; CHECK-S-NEXT: bl localCall@notoc
230-
; CHECK-S-NEXT: addi r1, r1, 32
231-
; CHECK-S-NEXT: ld r0, 16(r1)
232-
; CHECK-S-NEXT: mtlr r0
233-
; CHECK-S-NEXT: blr
215+
; CHECK-S-NEXT: b localCall@notoc
234216
entry:
235217
%0 = load i32, i32* @externGlobalVar, align 4
236218
%add = add nsw i32 %0, %a
@@ -243,16 +225,7 @@ define dso_local signext i32 @TailCallLocalNoGlobal(i32 signext %a) local_unname
243225
; CHECK-S: .localentry TailCallLocalNoGlobal, 1
244226
; CHECK-P9: .localentry TailCallLocalNoGlobal, .Lfunc_lep9-.Lfunc_gep9
245227
; CHECK-ALL: # %bb.0: # %entry
246-
; CHECK-S-NEXT: mflr r0
247-
; CHECK-S-NEXT: std r0, 16(r1)
248-
; CHECK-S-NEXT: stdu r1, -32(r1)
249-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
250-
; CHECK-S-NEXT: .cfi_offset lr, 16
251-
; CHECK-S-NEXT: bl localCall@notoc
252-
; CHECK-S-NEXT: addi r1, r1, 32
253-
; CHECK-S-NEXT: ld r0, 16(r1)
254-
; CHECK-S-NEXT: mtlr r0
255-
; CHECK-S-NEXT: blr
228+
; CHECK-S: b localCall@notoc
256229
entry:
257230
%call = tail call signext i32 @localCall(i32 signext %a)
258231
ret i32 %call
@@ -262,19 +235,10 @@ define dso_local signext i32 @TailCallExtern1(i32 signext %a) local_unnamed_addr
262235
; CHECK-ALL-LABEL: TailCallExtern1:
263236
; CHECK-S: .localentry TailCallExtern1
264237
; CHECK-S: # %bb.0: # %entry
265-
; CHECK-S-NEXT: mflr r0
266-
; CHECK-S-NEXT: std r0, 16(r1)
267-
; CHECK-S-NEXT: stdu r1, -32(r1)
268-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
269-
; CHECK-S-NEXT: .cfi_offset lr, 16
270-
; CHECK-S-NEXT: plwz r4, globalVar@PCREL(0), 1
238+
; CHECK-S: plwz r4, globalVar@PCREL(0), 1
271239
; CHECK-S-NEXT: add r3, r4, r3
272240
; CHECK-S-NEXT: extsw r3, r3
273-
; CHECK-S-NEXT: bl externCall@notoc
274-
; CHECK-S-NEXT: addi r1, r1, 32
275-
; CHECK-S-NEXT: ld r0, 16(r1)
276-
; CHECK-S-NEXT: mtlr r0
277-
; CHECK-S-NEXT: blr
241+
; CHECK-S-NEXT: b externCall@notoc
278242
entry:
279243
%0 = load i32, i32* @globalVar, align 4
280244
%add = add nsw i32 %0, %a
@@ -286,20 +250,11 @@ define dso_local signext i32 @TailCallExtern2(i32 signext %a) local_unnamed_addr
286250
; CHECK-ALL-LABEL: TailCallExtern2:
287251
; CHECK-S: .localentry TailCallExtern2
288252
; CHECK-S: # %bb.0: # %entry
289-
; CHECK-S-NEXT: mflr r0
290-
; CHECK-S-NEXT: std r0, 16(r1)
291-
; CHECK-S-NEXT: stdu r1, -32(r1)
292-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
293-
; CHECK-S-NEXT: .cfi_offset lr, 16
294-
; CHECK-S-NEXT: pld r4, externGlobalVar@got@pcrel(0), 1
253+
; CHECK-S: pld r4, externGlobalVar@got@pcrel(0), 1
295254
; CHECK-S-NEXT: lwz r4, 0(r4)
296255
; CHECK-S-NEXT: add r3, r4, r3
297256
; CHECK-S-NEXT: extsw r3, r3
298-
; CHECK-S-NEXT: bl externCall@notoc
299-
; CHECK-S-NEXT: addi r1, r1, 32
300-
; CHECK-S-NEXT: ld r0, 16(r1)
301-
; CHECK-S-NEXT: mtlr r0
302-
; CHECK-S-NEXT: blr
257+
; CHECK-S-NEXT: b externCall@notoc
303258
entry:
304259
%0 = load i32, i32* @externGlobalVar, align 4
305260
%add = add nsw i32 %0, %a
@@ -311,16 +266,8 @@ define dso_local signext i32 @TailCallExternNoGlobal(i32 signext %a) local_unnam
311266
; CHECK-ALL-LABEL: TailCallExternNoGlobal:
312267
; CHECK-S: .localentry TailCallExternNoGlobal, 1
313268
; CHECK-S-NEXT: # %bb.0: # %entry
314-
; CHECK-S-NEXT: mflr r0
315-
; CHECK-S-NEXT: std r0, 16(r1)
316-
; CHECK-S-NEXT: stdu r1, -32(r1)
317-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
318-
; CHECK-S-NEXT: .cfi_offset lr, 16
319-
; CHECK-S-NEXT: bl externCall@notoc
320-
; CHECK-S-NEXT: addi r1, r1, 32
321-
; CHECK-S-NEXT: ld r0, 16(r1)
322-
; CHECK-S-NEXT: mtlr r0
323-
; CHECK-S-NEXT: blr
269+
; CHECK-S-NEXT: b externCall@notoc
270+
; CHECK-S-NEXT: #TC_RETURNd8 externCall@notoc
324271
entry:
325272
%call = tail call signext i32 @externCall(i32 signext %a)
326273
ret i32 %call
@@ -443,18 +390,10 @@ entry:
443390
define dso_local signext i32 @IndirectCallOnly(i32 signext %a, i32 (i32)* nocapture %call_param) local_unnamed_addr {
444391
; CHECK-ALL-LABEL: IndirectCallOnly:
445392
; CHECK-S: # %bb.0: # %entry
446-
; CHECK-S-NEXT: mflr r0
447-
; CHECK-S-NEXT: std r0, 16(r1)
448-
; CHECK-S-NEXT: stdu r1, -32(r1)
449-
; CHECK-S-NEXT: .cfi_def_cfa_offset 32
450-
; CHECK-S-NEXT: .cfi_offset lr, 16
451393
; CHECK-S-NEXT: mtctr r4
452394
; CHECK-S-NEXT: mr r12, r4
453-
; CHECK-S-NEXT: bctrl
454-
; CHECK-S-NEXT: addi r1, r1, 32
455-
; CHECK-S-NEXT: ld r0, 16(r1)
456-
; CHECK-S-NEXT: mtlr r0
457-
; CHECK-S-NEXT: blr
395+
; CHECK-S-NEXT: bctr
396+
; CHECK-S-NEXT: #TC_RETURNr8 ctr
458397
entry:
459398
%call = tail call signext i32 %call_param(i32 signext %a)
460399
ret i32 %call

0 commit comments

Comments
 (0)