aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ISelPattern.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-12-03 07:15:55 +0000
committerChris Lattner <sabre@nondot.org>2005-12-03 07:15:55 +0000
commita027ba885aa5efbffa1e6cc003dee61d8c99c8f7 (patch)
treed1a454aba76c7a18b04811e01154138928d9e7df /lib/Target/X86/X86ISelPattern.cpp
parent8e22200f2ba395243403e12adc4a09609fb7fd23 (diff)
Fix test/Regression/ExecutionEngine/2005-12-02-TailCallBug.ll and PR672.
This also fixes 177.mesa, the only program that fails with --enable-x86-fastcc turned on. Given a clean nightly tester run, we should be able to turn it on by default! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86ISelPattern.cpp')
-rw-r--r--lib/Target/X86/X86ISelPattern.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index 5c4594aa9e..28f799ee4a 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -3067,6 +3067,20 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) {
// TODO: handle jmp [mem]
if (!isDirect) {
+ // We do not want the register allocator to allocate CalleeReg to a callee
+ // saved register, as these will be restored before the JMP. To prevent
+ // this, emit explicit clobbers of callee saved regs here. A better way to
+ // solve this would be to specify that the register constraints of TAILJMPr
+ // only allow registers that are not callee saved, but we currently can't
+ // express that. This forces all four of these regs to be saved and
+ // reloaded for all functions with an indirect tail call.
+ // TODO: Improve this!
+ BuildMI(BB, X86::IMPLICIT_DEF, 4)
+ .addReg(X86::ESI, MachineOperand::Def)
+ .addReg(X86::EDI, MachineOperand::Def)
+ .addReg(X86::EBX, MachineOperand::Def)
+ .addReg(X86::EBP, MachineOperand::Def);
+
BuildMI(BB, X86::TAILJMPr, 1).addReg(CalleeReg);
} else if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Callee)){
BuildMI(BB, X86::TAILJMPd, 1).addGlobalAddress(GASD->getGlobal(), true);