diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1486,15 +1486,24 @@ if (LocalRS) LocalRS->enterBasicBlockEnd(*BB); + bool InsideCallSequence = false; for (MachineBasicBlock::iterator I = BB->end(); I != BB->begin();) { MachineInstr &MI = *std::prev(I); if (TII.isFrameInstr(MI)) { + InsideCallSequence = !TII.isFrameSetup(MI); SPAdj -= TII.getSPAdjust(MI); TFI.eliminateCallFramePseudoInstr(MF, *BB, &MI); continue; } + // If we are looking at a call sequence, we need to keep track of + // the SP adjustment made by each instruction in the sequence. + // This includes both the frame setup/destroy pseudos (handled above), + // as well as other instructions that have side effects w.r.t the SP. + if (InsideCallSequence) + SPAdj -= TII.getSPAdjust(MI); + // Step backwards to get the liveness state at (immedately after) MI. if (LocalRS) LocalRS->backward(MI); diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -408,23 +408,23 @@ } // To know whether a call adjusts the stack, we need information - // that is bound to the following ADJCALLSTACKUP pseudo. - // Look for the next ADJCALLSTACKUP that follows the call. + // that is bound to the preceding ADJCALLSTACKDOWN pseudo. + // Look for the next ADJCALLSTACKDOWN that precedes the call. if (MI.isCall()) { const MachineBasicBlock *MBB = MI.getParent(); - auto I = ++MachineBasicBlock::const_iterator(MI); - for (auto E = MBB->end(); I != E; ++I) { - if (I->getOpcode() == getCallFrameDestroyOpcode() || + auto I = MachineBasicBlock::const_iterator(MI); + for (auto E = MBB->begin(); I-- != E; ) { + if (I->getOpcode() == getCallFrameSetupOpcode() || I->isCall()) break; } - // If we could not find a frame destroy opcode, then it has already + // If we could not find a frame setup opcode, then it has already // been simplified, so we don't care. - if (I->getOpcode() != getCallFrameDestroyOpcode()) + if (I->getOpcode() != getCallFrameSetupOpcode()) return 0; - return -(I->getOperand(1).getImm()); + return I->getOperand(1).getImm(); } // Currently handle only PUSHes we can reasonably expect to see diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -143,6 +143,8 @@ int SPAdj, unsigned FIOperandNum, RegScavenger *RS = nullptr) const override; + bool supportsBackwardScavenger() const override { return true; } + /// findDeadCallerSavedReg - Return a caller-saved register that isn't live /// when it reaches the "return" instruction. We can then pop a stack object /// to this register without worry about clobbering it.