From: Chris Lattner Date: Fri, 13 May 2005 22:13:49 +0000 (+0000) Subject: Fix the problems with callee popped argument lists X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=06cebb456a43ecb385367de7526d5193b9a949e3;p=oota-llvm.git 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 --- diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index ba3644341cd..72403be898f 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(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.