From fab1e89de90902e0713b8af320fc83a412ef2dad Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 25 Feb 2014 00:59:14 +0000 Subject: MS ABI: Return sret parameters when using inalloca Previously the X86 backend would look for the sret attribute and handle this for us. inalloca takes that all away, so we have to do the return ourselves now. llvm-svn: 202097 --- clang/lib/CodeGen/CGCall.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'clang/lib/CodeGen/CGCall.cpp') diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a21e4783b60..756b0b2b605 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -940,7 +940,15 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { break; case ABIArgInfo::InAlloca: - resultType = llvm::Type::getVoidTy(getLLVMContext()); + if (retAI.getInAllocaSRet()) { + // sret things on win32 aren't void, they return the sret pointer. + QualType ret = FI.getReturnType(); + llvm::Type *ty = ConvertType(ret); + unsigned addressSpace = Context.getTargetAddressSpace(ret); + resultType = llvm::PointerType::get(ty, addressSpace); + } else { + resultType = llvm::Type::getVoidTy(getLLVMContext()); + } break; case ABIArgInfo::Indirect: { @@ -1779,7 +1787,17 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, switch (RetAI.getKind()) { case ABIArgInfo::InAlloca: - // Do nothing; aggregrates get evaluated directly into the destination. + // Aggregrates get evaluated directly into the destination. Sometimes we + // need to return the sret value in a register, though. + assert(hasAggregateEvaluationKind(RetTy)); + if (RetAI.getInAllocaSRet()) { + llvm::Function::arg_iterator EI = CurFn->arg_end(); + --EI; + llvm::Value *ArgStruct = EI; + llvm::Value *SRet = + Builder.CreateStructGEP(ArgStruct, RetAI.getInAllocaFieldIndex()); + RV = Builder.CreateLoad(SRet, "sret"); + } break; case ABIArgInfo::Indirect: { -- cgit v1.2.3