[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