Load folding tail call should not use ebp / rbp after it's popped. PEI

should use esp / rsp to reference frame instead.

llvm-svn: 102596
This commit is contained in:
Evan Cheng 2010-04-29 05:08:22 +00:00
parent bfebbd889a
commit da89f22f3d
2 changed files with 67 additions and 5 deletions

View File

@ -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;

View File

@ -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
}