diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index b0bf40304fc5d..028d1e26b730c 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1176,17 +1176,16 @@ class IRBuilderBase { return Insert(ReturnInst::Create(Context, V)); } - /// Create a sequence of N insertvalue instructions, - /// with one Value from the retVals array each, that build a aggregate - /// return value one value at a time, and a ret instruction to return - /// the resulting aggregate value. + /// Create a sequence of N insertvalue instructions, with one Value from the + /// RetVals array each, that build a aggregate return value one value at a + /// time, and a ret instruction to return the resulting aggregate value. /// /// This is a convenience function for code that uses aggregate return values /// as a vehicle for having multiple return values. - ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { + ReturnInst *CreateAggregateRet(ArrayRef RetVals) { Value *V = PoisonValue::get(getCurrentFunctionReturnType()); - for (unsigned i = 0; i != N; ++i) - V = CreateInsertValue(V, retVals[i], i, "mrv"); + for (size_t i = 0, N = RetVals.size(); i != N; ++i) + V = CreateInsertValue(V, RetVals[i], i, "mrv"); return Insert(ReturnInst::Create(Context, V)); } diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 65add3415b3bf..f54e885968fcb 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3486,7 +3486,7 @@ LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef B, LLVMValueRef *RetVals, unsigned N) { - return wrap(unwrap(B)->CreateAggregateRet(unwrap(RetVals), N)); + return wrap(unwrap(B)->CreateAggregateRet({unwrap(RetVals), N})); } LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 21daa5967108c..8c4daf56bbfa4 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -1415,4 +1415,25 @@ TEST_F(IRBuilderTest, finalizeSubprogram) { EXPECT_EQ(BarSP->getRetainedNodes()[0], Type); EXPECT_TRUE(FooSP->getRetainedNodes().empty()); } + +TEST_F(IRBuilderTest, CreateAggregateRet) { + IRBuilder<> Builder(BB); + // Terminate the function/block created in SetUp. + Builder.CreateRetVoid(); + + Type *AggType = + StructType::create(Ctx, {Builder.getInt8Ty(), Builder.getInt64Ty()}); + ConstantInt *RV0 = Builder.getInt8(5); + ConstantInt *RV1 = Builder.getInt64(55); + + FunctionType *FTy = FunctionType::get(AggType, /*isVarArg=*/false); + + Function *F1 = + Function::Create(FTy, Function::ExternalLinkage, "F2", M.get()); + BasicBlock *CalleeBB = BasicBlock::Create(Ctx, "", F1); + IRBuilder<> CalleeBuilder(CalleeBB); + CalleeBuilder.CreateAggregateRet({RV0, RV1}); + + EXPECT_FALSE(verifyModule(*M)); +} }