[llvm-commits] [llvm] r43027 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Arnold Schwaighofer arnold.schwaighofer at gmail.com
Tue Oct 16 02:05:01 PDT 2007


Author: arnolds
Date: Tue Oct 16 04:05:00 2007
New Revision: 43027

URL: http://llvm.org/viewvc/llvm-project?rev=43027&view=rev
Log:
Correction to tail call optimization code. The new return address
was stored to the acutal stack slot before the parameters were
lowered to their stack slot. This could cause arguments to be
overwritten by the return address if the called function had less
parameters than the caller function. The update should remove the
last failing test case of llc-beta: SPASS.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=43027&r1=43026&r2=43027&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 16 04:05:00 2007
@@ -707,10 +707,11 @@
     Operands.push_back(StackAdjustment);
     // Copy registers used by the call. Last operand is a flag so it is not
     // copied.
-    for(unsigned i=3; i < TailCall.getNumOperands()-1;i++) {
+    for (unsigned i=3; i < TailCall.getNumOperands()-1; i++) {
       Operands.push_back(Chain.getOperand(i));
     }
-    return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0], Operands.size()); 
+    return DAG.getNode(X86ISD::TC_RETURN, MVT::Other, &Operands[0], 
+                       Operands.size());
   }
   
   // Regular return.
@@ -1520,23 +1521,25 @@
   if (FPDiff < (MF.getInfo<X86MachineFunctionInfo>()->getTCReturnAddrDelta()))
     MF.getInfo<X86MachineFunctionInfo>()->setTCReturnAddrDelta(FPDiff);
 
-  // Adjust the ret address stack slot.
+  Chain = DAG.
+   getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, getPointerTy()));
+
+  // Adjust the Return address stack slot.
+  SDOperand RetAddrFrIdx, NewRetAddrFrIdx;
   if (FPDiff) {
     MVT::ValueType VT = is64Bit ? MVT::i64 : MVT::i32;
-    SDOperand RetAddrFrIdx = getReturnAddressFrameIndex(DAG); 
+    RetAddrFrIdx = getReturnAddressFrameIndex(DAG);
+    // Load the "old" Return address.
     RetAddrFrIdx = 
-      DAG.getLoad(VT, DAG.getEntryNode(),RetAddrFrIdx, NULL, 0);
-    // Emit a store of the saved ret value to the new location.
+      DAG.getLoad(VT, Chain,RetAddrFrIdx, NULL, 0);
+    // Calculate the new stack slot for the return address.
     int SlotSize = is64Bit ? 8 : 4;
     int NewReturnAddrFI = 
       MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize);
-    SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
-    Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, 0);
+    NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
+    Chain = SDOperand(RetAddrFrIdx.Val, 1);
   }
 
-  Chain = DAG.
-   getCALLSEQ_START(Chain, DAG.getConstant(NumBytesToBePushed, getPointerTy()));
-
   SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
   SmallVector<SDOperand, 8> MemOpChains;
   SmallVector<SDOperand, 8> MemOpChains2;
@@ -1592,6 +1595,7 @@
     InFlag = Chain.getValue(1);
   }
   InFlag = SDOperand();
+
   // Copy from stack slots to stack slot of a tail called function. This needs
   // to be done because if we would lower the arguments directly to their real
   // stack slot we might end up overwriting each other.
@@ -1637,6 +1641,10 @@
     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
                         &MemOpChains2[0], MemOpChains.size());
 
+  // Store the return address to the appropriate stack slot.
+  if (FPDiff)
+    Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx, NULL, 0);
+
   // ELF / PIC requires GOT in the EBX register before function calls via PLT
   // GOT pointer.
   // Does not work with tail call since ebx is not restored correctly by





More information about the llvm-commits mailing list