From: Reid Kleckner Date: Tue, 2 Sep 2014 18:42:44 +0000 (+0000) Subject: CodeGen: Handle va_start in the entry block X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f93099eb1ca6579eaea865c5f67dc0935d78e719;p=oota-llvm.git CodeGen: Handle va_start in the entry block Also fix a small copy-paste bug in X86ISelLowering where Chain should have been used in place of DAG.getEntryToken(). Fixes PR20828. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216929 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index ff8d3ad1501..1f58d7c301f 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -75,34 +75,26 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // instruction values that are used outside of the block that defines // them. Function::const_iterator BB = Fn->begin(), EB = Fn->end(); - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (const AllocaInst *AI = dyn_cast(I)) { - // Don't fold inalloca allocas or other dynamic allocas into the initial - // stack frame allocation, even if they are in the entry block. - if (!AI->isStaticAlloca()) - continue; - - if (const ConstantInt *CUI = dyn_cast(AI->getArraySize())) { - Type *Ty = AI->getAllocatedType(); - uint64_t TySize = TLI->getDataLayout()->getTypeAllocSize(Ty); - unsigned Align = - std::max((unsigned)TLI->getDataLayout()->getPrefTypeAlignment(Ty), - AI->getAlignment()); - - TySize *= CUI->getZExtValue(); // Get total allocated size. - if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. - - StaticAllocaMap[AI] = - MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI); - } - } - for (; BB != EB; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - // Look for dynamic allocas. if (const AllocaInst *AI = dyn_cast(I)) { - if (!AI->isStaticAlloca()) { + // Static allocas can be folded into the initial stack frame adjustment. + if (AI->isStaticAlloca()) { + const ConstantInt *CUI = cast(AI->getArraySize()); + Type *Ty = AI->getAllocatedType(); + uint64_t TySize = TLI->getDataLayout()->getTypeAllocSize(Ty); + unsigned Align = + std::max((unsigned)TLI->getDataLayout()->getPrefTypeAlignment(Ty), + AI->getAlignment()); + + TySize *= CUI->getZExtValue(); // Get total allocated size. + if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. + + StaticAllocaMap[AI] = + MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI); + + } else { unsigned Align = std::max( (unsigned)TLI->getDataLayout()->getPrefTypeAlignment( AI->getAllocatedType()), diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 1c10691250c..43e4ffeb963 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2547,11 +2547,11 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain, for (MCPhysReg Reg : ArgGPRs.slice(NumIntRegs)) { unsigned GPR = MF.addLiveIn(Reg, &X86::GR64RegClass); LiveGPRs.push_back( - DAG.getCopyFromReg(DAG.getEntryNode(), dl, GPR, MVT::i64)); + DAG.getCopyFromReg(Chain, dl, GPR, MVT::i64)); } if (!ArgXMMs.empty()) { unsigned AL = MF.addLiveIn(X86::AL, &X86::GR8RegClass); - ALVal = DAG.getCopyFromReg(DAG.getEntryNode(), dl, AL, MVT::i8); + ALVal = DAG.getCopyFromReg(Chain, dl, AL, MVT::i8); for (MCPhysReg Reg : ArgXMMs.slice(NumXMMRegs)) { unsigned XMMReg = MF.addLiveIn(Reg, &X86::VR128RegClass); LiveXMMRegs.push_back( diff --git a/test/CodeGen/X86/win64_vararg.ll b/test/CodeGen/X86/win64_vararg.ll index 1a51b2a64a7..8d7f2010a54 100644 --- a/test/CodeGen/X86/win64_vararg.ll +++ b/test/CodeGen/X86/win64_vararg.ll @@ -111,3 +111,22 @@ entry: %tmp = va_arg i8** %ap, i32 ret i32 %tmp } + +define void @sret_arg(i32* sret %agg.result, i8* nocapture readnone %format, ...) { +entry: + %ap = alloca i8* + %ap_i8 = bitcast i8** %ap to i8* + call void @llvm.va_start(i8* %ap_i8) + %tmp = va_arg i8** %ap, i32 + store i32 %tmp, i32* %agg.result + ret void +} +; CHECK-LABEL: sret_arg: +; CHECK: pushq +; CHECK-DAG: movq %r9, 40(%rsp) +; CHECK-DAG: movq %r8, 32(%rsp) +; CHECK: movl 32(%rsp), %[[tmp:[^ ]*]] +; CHECK: movl %[[tmp]], (%[[sret:[^ ]*]]) +; CHECK: movq %[[sret]], %rax +; CHECK: popq +; CHECK: retq