diff options
author | Chris Lattner <sabre@nondot.org> | 2005-05-13 22:13:49 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-05-13 22:13:49 +0000 |
commit | 06cebb456a43ecb385367de7526d5193b9a949e3 (patch) | |
tree | ed74a7788800d5ce6737748be78c4d59f17ee5dc /lib | |
parent | 678cfa9b199b8cd71b944bb5b19ea6335ced4fcb (diff) | |
download | llvm-06cebb456a43ecb385367de7526d5193b9a949e3.tar.gz llvm-06cebb456a43ecb385367de7526d5193b9a949e3.tar.bz2 llvm-06cebb456a43ecb385367de7526d5193b9a949e3.tar.xz |
Fix the problems with callee popped argument lists
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86ISelPattern.cpp | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index ba3644341c..72403be898 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -3746,7 +3746,43 @@ void ISel::Select(SDOperand N) { // Amount the callee added to the stack pointer. Tmp2 = cast<ConstantSDNode>(N.getOperand(2))->getValue(); - BuildMI(BB, X86::ADJCALLSTACKUP, 2).addImm(Tmp1).addImm(Tmp2); + + // This hackery is due to the fact that we don't want to emit this code: + // call foo + // mov vreg, EAX + // adjcallstackup + // + // Because if foo is a fastcc call and if vreg gets spilled, we might end up + // with this: + // call foo + // mov [ESP+offset], EAX ;; Offset doesn't consider the 12! + // sub ESP, 12 + // + // To avoid this, we force the adjcallstackup instruction before the 0, 1 or + // 2 moves that occur after the call. The correct way to fix this is to use + // target-specific DAG nodes in the call sequence. FIXME! + // + if (EnableFastCC) { + // This code should be safe. Be defensive for LLVM 1.5 release though. + assert(!BB->empty()); + MachineBasicBlock::iterator PrevI = --BB->end(); + if (PrevI->getOpcode() == X86::CALLpcrel32 || + PrevI->getOpcode() == X86::CALL32r) + ++PrevI; + else if (PrevI != BB->begin() && + ((--PrevI)->getOpcode() == X86::CALLpcrel32 || + PrevI->getOpcode() == X86::CALL32r)) + ++PrevI; + else if (PrevI != BB->begin() && + ((--PrevI)->getOpcode() == X86::CALLpcrel32 || + PrevI->getOpcode() == X86::CALL32r)) + ++PrevI; + else + PrevI = BB->end(); + BuildMI(*BB, PrevI, X86::ADJCALLSTACKUP, 2).addImm(Tmp1).addImm(Tmp2); + } else { + BuildMI(*BB, PrevI, X86::ADJCALLSTACKUP, 2).addImm(Tmp1).addImm(Tmp2); + } return; case ISD::MEMSET: { Select(N.getOperand(0)); // Select the chain. |