LLVM_DEBUG(dbgs() << "Frame instruction: " << MI << '\n');
return true;
}
+ const MachineFunction *MF = MI.getParent()->getParent();
+ const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
for (const MachineOperand &MO : MI.operands()) {
bool UseOrDefCSR = false;
if (MO.isReg()) {
// separately. An SP mentioned by a call instruction, we can ignore,
// though, as it's harmless and we do not want to effectively disable tail
// calls by forcing the restore point to post-dominate them.
- UseOrDefCSR = (!MI.isCall() && PhysReg == SP) ||
- RCI.getLastCalleeSavedAlias(PhysReg);
+ // PPC's LR is also not normally described as a callee-saved register in
+ // calling convention definitions, so we need to watch for it, too. An LR
+ // mentioned implicitly by a return (or "branch to link register")
+ // instruction we can ignore, otherwise we may pessimize shrinkwrapping.
+ UseOrDefCSR =
+ (!MI.isCall() && PhysReg == SP) ||
+ RCI.getLastCalleeSavedAlias(PhysReg) ||
+ (!MI.isReturn() && TRI->isNonallocatableRegisterCalleeSave(PhysReg));
} else if (MO.isRegMask()) {
// Check if this regmask clobbers any of the CSRs.
for (unsigned Reg : getCurrentCSRs(RS)) {
define dso_local signext i32 @ClobberLR_BR(i32 signext %in) #0 {
; PPC64LE-LABEL: ClobberLR_BR:
; PPC64LE: # %bb.0: # %entry
+; PPC64LE-NEXT: mflr r0
+; PPC64LE-NEXT: std r0, 16(r1)
+; PPC64LE-NEXT: stdu r1, -32(r1)
; PPC64LE-NEXT: #APP
; PPC64LE-NEXT: nop
; PPC64LE-NEXT: #NO_APP
-; PPC64LE-NEXT: # %bb.1: # %return
+; PPC64LE-NEXT: .LBB3_1: # %return
; PPC64LE-NEXT: extsw r3, r3
-; PPC64LE-NEXT: blr
-; PPC64LE-NEXT: .Ltmp0: # Block address taken
-; PPC64LE-NEXT: .LBB3_2: # %return_early
-; PPC64LE-NEXT: mflr r0
-; PPC64LE-NEXT: std r0, 16(r1)
-; PPC64LE-NEXT: stdu r1, -32(r1)
-; PPC64LE-NEXT: li r3, 0
; PPC64LE-NEXT: addi r1, r1, 32
; PPC64LE-NEXT: ld r0, 16(r1)
; PPC64LE-NEXT: mtlr r0
-; PPC64LE-NEXT: extsw r3, r3
; PPC64LE-NEXT: blr
+; PPC64LE-NEXT: .Ltmp0: # Block address taken
+; PPC64LE-NEXT: .LBB3_2: # %return_early
+; PPC64LE-NEXT: li r3, 0
+; PPC64LE-NEXT: b .LBB3_1
;
; PPC64BE-LABEL: ClobberLR_BR:
; PPC64BE: # %bb.0: # %entry
+; PPC64BE-NEXT: mflr r0
+; PPC64BE-NEXT: std r0, 16(r1)
+; PPC64BE-NEXT: stdu r1, -48(r1)
; PPC64BE-NEXT: #APP
; PPC64BE-NEXT: nop
; PPC64BE-NEXT: #NO_APP
-; PPC64BE-NEXT: # %bb.1: # %return
+; PPC64BE-NEXT: .LBB3_1: # %return
; PPC64BE-NEXT: extsw r3, r3
-; PPC64BE-NEXT: blr
-; PPC64BE-NEXT: .Ltmp0: # Block address taken
-; PPC64BE-NEXT: .LBB3_2: # %return_early
-; PPC64BE-NEXT: mflr r0
-; PPC64BE-NEXT: std r0, 16(r1)
-; PPC64BE-NEXT: stdu r1, -48(r1)
-; PPC64BE-NEXT: li r3, 0
; PPC64BE-NEXT: addi r1, r1, 48
; PPC64BE-NEXT: ld r0, 16(r1)
; PPC64BE-NEXT: mtlr r0
-; PPC64BE-NEXT: extsw r3, r3
; PPC64BE-NEXT: blr
+; PPC64BE-NEXT: .Ltmp0: # Block address taken
+; PPC64BE-NEXT: .LBB3_2: # %return_early
+; PPC64BE-NEXT: li r3, 0
+; PPC64BE-NEXT: b .LBB3_1
entry:
callbr void asm sideeffect "nop", "X,~{lr}"(i8* blockaddress(@ClobberLR_BR, %return_early))
to label %return [label %return_early]