[llvm-commits] [llvm] r58415 - in /llvm/trunk: lib/Target/CellSPU/SPUAsmPrinter.cpp lib/Target/CellSPU/SPUISelLowering.cpp test/CodeGen/CellSPU/call.ll

Scott Michel scottm at aero.org
Wed Oct 29 18:51:49 PDT 2008


Author: pingbak
Date: Wed Oct 29 20:51:48 2008
New Revision: 58415

URL: http://llvm.org/viewvc/llvm-project?rev=58415&view=rev
Log:
Resolve bug 2947: vararg-marked functions must spill registers R3-R79 to stack
so that va_start/va_arg/et.al. will walk arguments correctly for Cell SPU.

N.B.: Because neither clang nor llvm-gcc-4.2 can be built for CellSPU, this is
still unexorcised code.

Modified:
    llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
    llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp
    llvm/trunk/test/CodeGen/CellSPU/call.ll

Modified: llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp?rev=58415&r1=58414&r2=58415&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUAsmPrinter.cpp Wed Oct 29 20:51:48 2008
@@ -188,8 +188,10 @@
       const MachineOperand &MO = MI->getOperand(OpNo);
       assert(MO.isImm() &&
              "printMemRegImmS10 first operand is not immedate");
-      printS10ImmOperand(MI, OpNo);
-      O << "(";
+      int64_t value = int64_t(MI->getOperand(OpNo).getImm());
+      assert((value >= -(1 << (9+4)) && value <= (1 << (9+4)) - 1)
+             && "Invalid dform s10 offset argument");
+      O << value << "(";
       printOperand(MI, OpNo+1);
       O << ")";
     }

Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=58415&r1=58414&r2=58415&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Oct 29 20:51:48 2008
@@ -460,10 +460,7 @@
 
 MVT SPUTargetLowering::getSetCCResultType(const SDValue &Op) const {
   MVT VT = Op.getValueType();
-  if (VT.isInteger())
-    return VT;
-  else
-    return MVT::i32;
+  return (VT.isInteger() ? VT : MVT(MVT::i32));
 }
 
 //===----------------------------------------------------------------------===//
@@ -926,7 +923,7 @@
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MachineRegisterInfo &RegInfo = MF.getRegInfo();
-  SmallVector<SDValue, 8> ArgValues;
+  SmallVector<SDValue, 48> ArgValues;
   SDValue Root = Op.getOperand(0);
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
 
@@ -942,98 +939,57 @@
   // Add DAG nodes to load the arguments or copy them out of registers.
   for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1;
        ArgNo != e; ++ArgNo) {
-    SDValue ArgVal;
-    bool needsLoad = false;
     MVT ObjectVT = Op.getValue(ArgNo).getValueType();
     unsigned ObjSize = ObjectVT.getSizeInBits()/8;
+    SDValue ArgVal;
 
-    switch (ObjectVT.getSimpleVT()) {
-    default: {
-      cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
-           << ObjectVT.getMVTString()
-           << "\n";
-      abort();
-    }
-    case MVT::i8:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R8CRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i8);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::i16:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R16CRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i16);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::i32:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32CRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::i64:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64CRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::f32:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R32FPRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f32);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::f64:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::R64FPRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::f64);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::v2f64:
-    case MVT::v4f32:
-    case MVT::v2i64:
-    case MVT::v4i32:
-    case MVT::v8i16:
-    case MVT::v16i8:
-      if (!isVarArg && ArgRegIdx < NumArgRegs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&SPU::VECREGRegClass);
-        RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
-        ++ArgRegIdx;
-      } else {
-        needsLoad = true;
+    if (ArgRegIdx < NumArgRegs) {
+      const TargetRegisterClass *ArgRegClass;
+
+      switch (ObjectVT.getSimpleVT()) {
+      default: {
+	cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: "
+	     << ObjectVT.getMVTString()
+	     << "\n";
+	abort();
+      }
+      case MVT::i8:
+	ArgRegClass = &SPU::R8CRegClass;
+	break;
+      case MVT::i16:
+	ArgRegClass = &SPU::R16CRegClass;
+	break;
+      case MVT::i32:
+	ArgRegClass = &SPU::R32CRegClass;
+	break;
+      case MVT::i64:
+	ArgRegClass = &SPU::R64CRegClass;
+	break;
+      case MVT::f32:
+	ArgRegClass = &SPU::R32FPRegClass;
+	break;
+      case MVT::f64:
+	ArgRegClass = &SPU::R64FPRegClass;
+	break;
+      case MVT::v2f64:
+      case MVT::v4f32:
+      case MVT::v2i64:
+      case MVT::v4i32:
+      case MVT::v8i16:
+      case MVT::v16i8:
+	ArgRegClass = &SPU::VECREGRegClass;
+	++ArgRegIdx;
+	break;
       }
-      break;
-    }
 
-    // We need to load the argument to a virtual register if we determined above
-    // that we ran out of physical registers of the appropriate type
-    if (needsLoad) {
+      unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass);
+      RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
+      ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
+      ++ArgRegIdx;
+    } else {
+      // We need to load the argument to a virtual register if we determined
+      // above that we ran out of physical registers of the appropriate type
+      // or we're forced to do vararg
       int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
       SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
       ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
@@ -1041,30 +997,31 @@
     }
 
     ArgValues.push_back(ArgVal);
+    // Update the chain
+    Root = ArgVal.getOperand(0);
   }
 
-  // If the function takes variable number of arguments, make a frame index for
-  // the start of the first vararg value... for expansion of llvm.va_start.
+  // vararg handling:
   if (isVarArg) {
-    VarArgsFrameIndex = MFI->CreateFixedObject(PtrVT.getSizeInBits()/8,
-                                               ArgOffset);
-    SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
-    // If this function is vararg, store any remaining integer argument regs to
-    // their spots on the stack so that they may be loaded by deferencing the
-    // result of va_next.
-    SmallVector<SDValue, 8> MemOps;
+    // unsigned int ptr_size = PtrVT.getSizeInBits() / 8;
+    // We will spill (79-3)+1 registers to the stack
+    SmallVector<SDValue, 79-3+1> MemOps;
+
+    // Create the frame slot
+
     for (; ArgRegIdx != NumArgRegs; ++ArgRegIdx) {
-      unsigned VReg = RegInfo.createVirtualRegister(&SPU::GPRCRegClass);
-      RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg);
-      SDValue Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
-      SDValue Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
+      VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset);
+      SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
+      SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8);
+      SDValue Store = DAG.getStore(Root, ArgVal, FIN, NULL, 0);
+      Root = Store.getOperand(0);
       MemOps.push_back(Store);
-      // Increment the address by four for the next argument to store
-      SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
-      FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
+
+      // Increment address by stack slot size for the next stored argument
+      ArgOffset += StackSlotSize;
     }
     if (!MemOps.empty())
-      Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
+      Root = DAG.getNode(ISD::TokenFactor,MVT::Other,&MemOps[0],MemOps.size());
   }
 
   ArgValues.push_back(Root);
@@ -1093,10 +1050,6 @@
 LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
   CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
   SDValue Chain = TheCall->getChain();
-#if 0
-  bool isVarArg   = TheCall->isVarArg();
-  bool isTailCall = TheCall->isTailCall();
-#endif
   SDValue Callee    = TheCall->getCallee();
   unsigned NumOps     = TheCall->getNumArgs();
   unsigned StackSlotSize = SPUFrameInfo::stackSlotSize();

Modified: llvm/trunk/test/CodeGen/CellSPU/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call.ll?rev=58415&r1=58414&r2=58415&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/call.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/call.ll Wed Oct 29 20:51:48 2008
@@ -1,6 +1,7 @@
 ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
 ; RUN: grep brsl    %t1.s | count 1
 ; RUN: grep brasl   %t1.s | count 1
+; RUN: grep stqd    %t1.s | count 81
 
 target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
 target triple = "spu"
@@ -18,3 +19,10 @@
 entry:
   ret i32 0
 }
+
+; vararg call: ensure that all caller-saved registers are spilled to the
+; stack:
+define i32 @stub_2(...) {
+entry:
+  ret i32 0
+}





More information about the llvm-commits mailing list