Load folding tail call should not use ebp / rbp after it's popped. PEI
authorEvan Cheng <evan.cheng@apple.com>
Thu, 29 Apr 2010 05:08:22 +0000 (05:08 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 29 Apr 2010 05:08:22 +0000 (05:08 +0000)
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
test/CodeGen/X86/sibcall-2.ll [new file with mode: 0644]

index 6bf9be5b276702277a44a94a970368cbfaf47557..a3e04b098600664448437d1a8109a1eafb639080 100644 (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;
diff --git a/test/CodeGen/X86/sibcall-2.ll b/test/CodeGen/X86/sibcall-2.ll
new file mode 100644 (file)
index 0000000..f8a7465
--- /dev/null
@@ -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
+}