[llvm] r265112 - [PPC64] Bug fix: when enabling sibling-call-opt and shrink-wrapping, the tail call branch instruction might disappear
Chuang-Yu Cheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 31 23:44:33 PDT 2016
Author: cycheng
Date: Fri Apr 1 01:44:32 2016
New Revision: 265112
URL: http://llvm.org/viewvc/llvm-project?rev=265112&view=rev
Log:
[PPC64] Bug fix: when enabling sibling-call-opt and shrink-wrapping, the tail call branch instruction might disappear
Bug Pattern:
# BB#0: # %entry
cmpldi 3, 0
beq- 0, .LBB0_2
# BB#1: # %exit
lwz 4, 0(3)
#TC_RETURNd8 LVComputationKind 0
.LBB0_2: # %cond.false
mflr 0
std 0, 16(1)
stdu 1, -96(1)
.Ltmp0:
.cfi_def_cfa_offset 96
.Ltmp1:
.cfi_offset lr, 16
bl __assert_fail
nop
The branch instruction for tail call return is not generated, because the
shrink-wrapping pass choosing a new Restore Point: %cond.false, so %exit
block is not sent to emitEpilogue, that's why the branch is not generated.
Thanks Kit's opinions!
Reviewers: nemanjai hfinkel tjablin kbarton
http://reviews.llvm.org/D17606
Modified:
llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h
Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp?rev=265112&r1=265111&r2=265112&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp Fri Apr 1 01:44:32 2016
@@ -1315,36 +1315,53 @@ void PPCFrameLowering::emitEpilogue(Mach
.addReg(FPReg)
.addReg(ScratchReg);
}
- } else if (RetOpcode == PPC::TCRETURNdi) {
- MBBI = MBB.getLastNonDebugInstr();
- MachineOperand &JumpTarget = MBBI->getOperand(0);
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
- addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
- } else if (RetOpcode == PPC::TCRETURNri) {
- MBBI = MBB.getLastNonDebugInstr();
- assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
- } else if (RetOpcode == PPC::TCRETURNai) {
- MBBI = MBB.getLastNonDebugInstr();
- MachineOperand &JumpTarget = MBBI->getOperand(0);
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
- } else if (RetOpcode == PPC::TCRETURNdi8) {
- MBBI = MBB.getLastNonDebugInstr();
- MachineOperand &JumpTarget = MBBI->getOperand(0);
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
- addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
- } else if (RetOpcode == PPC::TCRETURNri8) {
- MBBI = MBB.getLastNonDebugInstr();
- assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
- } else if (RetOpcode == PPC::TCRETURNai8) {
- MBBI = MBB.getLastNonDebugInstr();
- MachineOperand &JumpTarget = MBBI->getOperand(0);
- BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
+ } else {
+ createTailCallBranchInstr(MBB);
}
}
}
+void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {
+ MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
+ DebugLoc dl;
+
+ if (MBBI != MBB.end())
+ dl = MBBI->getDebugLoc();
+
+ const PPCInstrInfo &TII =
+ *static_cast<const PPCInstrInfo *>(Subtarget.getInstrInfo());
+
+ // Create branch instruction for pseudo tail call return instruction
+ unsigned RetOpcode = MBBI->getOpcode();
+ if (RetOpcode == PPC::TCRETURNdi) {
+ MBBI = MBB.getLastNonDebugInstr();
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB)).
+ addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
+ } else if (RetOpcode == PPC::TCRETURNri) {
+ MBBI = MBB.getLastNonDebugInstr();
+ assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR));
+ } else if (RetOpcode == PPC::TCRETURNai) {
+ MBBI = MBB.getLastNonDebugInstr();
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm());
+ } else if (RetOpcode == PPC::TCRETURNdi8) {
+ MBBI = MBB.getLastNonDebugInstr();
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILB8)).
+ addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset());
+ } else if (RetOpcode == PPC::TCRETURNri8) {
+ MBBI = MBB.getLastNonDebugInstr();
+ assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBCTR8));
+ } else if (RetOpcode == PPC::TCRETURNai8) {
+ MBBI = MBB.getLastNonDebugInstr();
+ MachineOperand &JumpTarget = MBBI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm());
+ }
+}
+
void PPCFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
@@ -1421,6 +1438,18 @@ void PPCFrameLowering::processFunctionBe
MachineFrameInfo *FFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+ // If the function is shrink-wrapped, and if the function has a tail call, the
+ // tail call might not be in the new RestoreBlock, so real branch instruction
+ // won't be generated by emitEpilogue(), because shrink-wrap has chosen new
+ // RestoreBlock. So we handle this case here.
+ if (FFI->getSavePoint() && FFI->hasTailCall()) {
+ MachineBasicBlock *RestoreBlock = FFI->getRestorePoint();
+ for (MachineBasicBlock &MBB : MF) {
+ if (MBB.isReturnBlock() && (&MBB) != RestoreBlock)
+ createTailCallBranchInstr(MBB);
+ }
+ }
+
// Early exit if no callee saved registers are modified!
if (CSI.empty() && !needsFP(MF)) {
addScavengingSpillSlot(MF, RS);
Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h?rev=265112&r1=265111&r2=265112&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.h Fri Apr 1 01:44:32 2016
@@ -66,6 +66,13 @@ class PPCFrameLowering: public TargetFra
unsigned *SR2 = nullptr) const;
bool twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const;
+ /**
+ * \brief Create branch instruction for PPC::TCRETURN* (tail call return)
+ *
+ * \param[in] MBB that is terminated by PPC::TCRETURN*
+ */
+ void createTailCallBranchInstr(MachineBasicBlock &MBB) const;
+
public:
PPCFrameLowering(const PPCSubtarget &STI);
More information about the llvm-commits
mailing list