From 3f54c64a9834f949fdd3abcf8bb68e596c87a6bd Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 29 Apr 2010 05:08:22 +0000 Subject: [PATCH] Load folding tail call should not use ebp / rbp after it's popped. PEI should use esp / rsp to reference frame instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102596 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86RegisterInfo.cpp | 20 +++++++++--- test/CodeGen/X86/sibcall-2.ll | 52 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/sibcall-2.ll diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 6bf9be5b276..a3e04b09860 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -608,8 +608,12 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int FrameIndex = MI.getOperand(i).getIndex(); unsigned BasePtr; + unsigned Opc = MI.getOpcode(); + bool AfterFPPop = Opc == X86::TAILJMPm64 || Opc == X86::TAILJMPm; if (needsStackRealignment(MF)) BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr); + else if (AfterFPPop) + BasePtr = StackPtr; else BasePtr = (hasFP(MF) ? FramePtr : StackPtr); @@ -618,16 +622,22 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i).ChangeToRegister(BasePtr, false); // Now add the frame object offset to the offset from EBP. + int FIOffset; + if (AfterFPPop) { + // Tail call jmp happens after FP is popped. + const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + FIOffset = MFI->getObjectOffset(FrameIndex) - TFI.getOffsetOfLocalArea(); + } else + FIOffset = getFrameIndexOffset(MF, FrameIndex); + if (MI.getOperand(i+3).isImm()) { // Offset is a 32-bit integer. - int Offset = getFrameIndexOffset(MF, FrameIndex) + - (int)(MI.getOperand(i + 3).getImm()); - + int Offset = FIOffset + (int)(MI.getOperand(i + 3).getImm()); MI.getOperand(i + 3).ChangeToImmediate(Offset); } else { // Offset is symbolic. This is extremely rare. - uint64_t Offset = getFrameIndexOffset(MF, FrameIndex) + - (uint64_t)MI.getOperand(i+3).getOffset(); + uint64_t Offset = FIOffset + (uint64_t)MI.getOperand(i+3).getOffset(); MI.getOperand(i+3).setOffset(Offset); } return 0; diff --git a/test/CodeGen/X86/sibcall-2.ll b/test/CodeGen/X86/sibcall-2.ll new file mode 100644 index 00000000000..f8a746563b5 --- /dev/null +++ b/test/CodeGen/X86/sibcall-2.ll @@ -0,0 +1,52 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin -disable-fp-elim | FileCheck %s -check-prefix=32 +; RUN: llc < %s -mtriple=x86_64-apple-darwin -disable-fp-elim | FileCheck %s -check-prefix=64 + +; Tail call should not use ebp / rbp after it's popped. Use esp / rsp. + +define void @t1(i8* nocapture %value) nounwind { +entry: +; 32: t1: +; 32: jmpl *4(%esp) + +; 64: t1: +; 64: jmpq *%rdi + %0 = bitcast i8* %value to void ()* + tail call void %0() nounwind + ret void +} + +define void @t2(i32 %a, i8* nocapture %value) nounwind { +entry: +; 32: t2: +; 32: jmpl *8(%esp) + +; 64: t2: +; 64: jmpq *%rsi + %0 = bitcast i8* %value to void ()* + tail call void %0() nounwind + ret void +} + +define void @t3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i8* nocapture %value) nounwind { +entry: +; 32: t3: +; 32: jmpl *28(%esp) + +; 64: t3: +; 64: jmpq *8(%rsp) + %0 = bitcast i8* %value to void ()* + tail call void %0() nounwind + ret void +} + +define void @t4(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i8* nocapture %value) nounwind { +entry: +; 32: t4: +; 32: jmpl *32(%esp) + +; 64: t4: +; 64: jmpq *16(%rsp) + %0 = bitcast i8* %value to void ()* + tail call void %0() nounwind + ret void +} -- 2.34.1