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
This commit is contained in:
Jakob Stoklund Olesen 2010-10-11 20:43:09 +00:00
parent e2a0b6841a
commit 6c4353ecee
2 changed files with 29 additions and 33 deletions

View File

@ -1715,24 +1715,14 @@ PPCTargetLowering::LowerFormalArguments_SVR4(
FuncInfo->setVarArgsFrameIndex(MFI->CreateStackObject(Depth, 8, false)); FuncInfo->setVarArgsFrameIndex(MFI->CreateStackObject(Depth, 8, false));
SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
// The fixed integer arguments of a variadic function are // The fixed integer arguments of a variadic function are stored to the
// stored to the VarArgsFrameIndex on the stack. // VarArgsFrameIndex on the stack so that they may be loaded by deferencing
unsigned GPRIndex = 0; // the result of va_next.
for (; GPRIndex != FuncInfo->getVarArgsNumGPR(); ++GPRIndex) { for (unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT); // Get an existing live-in vreg, or add a new one.
SDValue Store = DAG.getStore(Chain, dl, Val, FIN, MachinePointerInfo(), unsigned VReg = MF.getRegInfo().getLiveInVirtReg(GPArgRegs[GPRIndex]);
false, false, 0); if (!VReg)
MemOps.push_back(Store); VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
// 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);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, 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 // FIXME 32-bit SVR4: We only need to save FP argument registers if CR bit 6
// is set. // is set.
// The double arguments are stored to the VarArgsFrameIndex // The double arguments are stored to the VarArgsFrameIndex
// on the stack. // on the stack.
unsigned FPRIndex = 0; for (unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
for (FPRIndex = 0; FPRIndex != FuncInfo->getVarArgsNumFPR(); ++FPRIndex) { // Get an existing live-in vreg, or add a new one.
SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64); unsigned VReg = MF.getRegInfo().getLiveInVirtReg(FPArgRegs[FPRIndex]);
SDValue Store = DAG.getStore(Chain, dl, Val, FIN, MachinePointerInfo(), if (!VReg)
false, false, 0); VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
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);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64);
SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,

View File

@ -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
}