From 6c4353ecee6fa1824910ed28d73e3c83d190bc11 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 11 Oct 2010 20:43:09 +0000 Subject: [PATCH] PowerPC varargs functions store live-in registers on the stack. Make sure we use virtual registers for those stores since RegAllocFast requires that each live physreg only be used once. This fixes PR8357. llvm-svn: 116222 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 46 ++++++------------- .../PowerPC/2010-10-11-Fast-Varargs.ll | 16 +++++++ 2 files changed, 29 insertions(+), 33 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/2010-10-11-Fast-Varargs.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 618e5c1c4dd5..06fececdc367 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1715,24 +1715,14 @@ PPCTargetLowering::LowerFormalArguments_SVR4( FuncInfo->setVarArgsFrameIndex(MFI->CreateStackObject(Depth, 8, false)); SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); - // The fixed integer arguments of a variadic function are - // stored to the VarArgsFrameIndex on the stack. - unsigned GPRIndex = 0; - for (; GPRIndex != FuncInfo->getVarArgsNumGPR(); ++GPRIndex) { - SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT); - SDValue Store = DAG.getStore(Chain, dl, Val, FIN, MachinePointerInfo(), - false, false, 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, dl, PtrOff.getValueType(), FIN, PtrOff); - } - - // 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. - for (; GPRIndex != NumGPArgRegs; ++GPRIndex) { - unsigned VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass); + // The fixed integer arguments of a variadic function are stored to the + // VarArgsFrameIndex on the stack so that they may be loaded by deferencing + // the result of va_next. + for (unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) { + // Get an existing live-in vreg, or add a new one. + unsigned VReg = MF.getRegInfo().getLiveInVirtReg(GPArgRegs[GPRIndex]); + if (!VReg) + VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, @@ -1745,23 +1735,13 @@ PPCTargetLowering::LowerFormalArguments_SVR4( // FIXME 32-bit SVR4: We only need to save FP argument registers if CR bit 6 // is set. - // The double arguments are stored to the VarArgsFrameIndex // on the stack. - unsigned FPRIndex = 0; - for (FPRIndex = 0; FPRIndex != FuncInfo->getVarArgsNumFPR(); ++FPRIndex) { - SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64); - SDValue Store = DAG.getStore(Chain, dl, Val, FIN, MachinePointerInfo(), - false, false, 0); - MemOps.push_back(Store); - // Increment the address by eight for the next argument to store - SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8, - PtrVT); - FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff); - } - - for (; FPRIndex != NumFPArgRegs; ++FPRIndex) { - unsigned VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass); + for (unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) { + // Get an existing live-in vreg, or add a new one. + unsigned VReg = MF.getRegInfo().getLiveInVirtReg(FPArgRegs[FPRIndex]); + if (!VReg) + VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, diff --git a/llvm/test/CodeGen/PowerPC/2010-10-11-Fast-Varargs.ll b/llvm/test/CodeGen/PowerPC/2010-10-11-Fast-Varargs.ll new file mode 100644 index 000000000000..da77b2878543 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/2010-10-11-Fast-Varargs.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -O0 +; PR8357 +target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32" +target triple = "powerpc-unknown-freebsd9.0" + +; RegAllocFast requires that each physreg only be used once. The varargs +; lowering code needs to use virtual registers when storing live-in registers on +; the stack. + +define i32 @testing(i32 %x, float %a, ...) nounwind { + %1 = alloca i32, align 4 + %2 = alloca float, align 4 + store i32 %x, i32* %1, align 4 + store float %a, float* %2, align 4 + ret i32 0 +}