aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp')
-rw-r--r--llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index 7b54ae6..d923b25 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -5989,6 +5989,156 @@ TEST_F(OpenMPIRBuilderTest, TargetRegionDevice) {
EXPECT_TRUE(isa<ReturnInst>(ExitBlock->getFirstNonPHI()));
}
+TEST_F(OpenMPIRBuilderTest, ConstantAllocaRaise) {
+ OpenMPIRBuilder OMPBuilder(*M);
+ OMPBuilder.setConfig(
+ OpenMPIRBuilderConfig(true, false, false, false, false, false, false));
+ OMPBuilder.initialize();
+
+ F->setName("func");
+ IRBuilder<> Builder(BB);
+ OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
+
+ LoadInst *Value = nullptr;
+ StoreInst *TargetStore = nullptr;
+ llvm::SmallVector<llvm::Value *, 1> CapturedArgs = {
+ Constant::getNullValue(PointerType::get(Ctx, 0))};
+
+ auto SimpleArgAccessorCB =
+ [&](llvm::Argument &Arg, llvm::Value *Input, llvm::Value *&RetVal,
+ llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,
+ llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP) {
+ if (!OMPBuilder.Config.isTargetDevice()) {
+ RetVal = cast<llvm::Value>(&Arg);
+ return CodeGenIP;
+ }
+
+ Builder.restoreIP(AllocaIP);
+
+ llvm::Value *Addr = Builder.CreateAlloca(
+ Arg.getType()->isPointerTy()
+ ? Arg.getType()
+ : Type::getInt64Ty(Builder.getContext()),
+ OMPBuilder.M.getDataLayout().getAllocaAddrSpace());
+ llvm::Value *AddrAscast =
+ Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Input->getType());
+ Builder.CreateStore(&Arg, AddrAscast);
+
+ Builder.restoreIP(CodeGenIP);
+
+ RetVal = Builder.CreateLoad(Arg.getType(), AddrAscast);
+
+ return Builder.saveIP();
+ };
+
+ llvm::OpenMPIRBuilder::MapInfosTy CombinedInfos;
+ auto GenMapInfoCB = [&](llvm::OpenMPIRBuilder::InsertPointTy codeGenIP)
+ -> llvm::OpenMPIRBuilder::MapInfosTy & {
+ CreateDefaultMapInfos(OMPBuilder, CapturedArgs, CombinedInfos);
+ return CombinedInfos;
+ };
+
+ llvm::Value *RaiseAlloca = nullptr;
+
+ auto BodyGenCB = [&](OpenMPIRBuilder::InsertPointTy AllocaIP,
+ OpenMPIRBuilder::InsertPointTy CodeGenIP)
+ -> OpenMPIRBuilder::InsertPointTy {
+ Builder.restoreIP(CodeGenIP);
+ RaiseAlloca = Builder.CreateAlloca(Builder.getInt32Ty());
+ Value = Builder.CreateLoad(Type::getInt32Ty(Ctx), CapturedArgs[0]);
+ TargetStore = Builder.CreateStore(Value, RaiseAlloca);
+ return Builder.saveIP();
+ };
+
+ IRBuilder<>::InsertPoint EntryIP(&F->getEntryBlock(),
+ F->getEntryBlock().getFirstInsertionPt());
+ TargetRegionEntryInfo EntryInfo("parent", /*DeviceID=*/1, /*FileID=*/2,
+ /*Line=*/3, /*Count=*/0);
+
+ Builder.restoreIP(
+ OMPBuilder.createTarget(Loc, EntryIP, EntryIP, EntryInfo, /*NumTeams=*/-1,
+ /*NumThreads=*/0, CapturedArgs, GenMapInfoCB,
+ BodyGenCB, SimpleArgAccessorCB));
+
+ Builder.CreateRetVoid();
+ OMPBuilder.finalize();
+
+ // Check outlined function
+ EXPECT_FALSE(verifyModule(*M, &errs()));
+ EXPECT_NE(TargetStore, nullptr);
+ Function *OutlinedFn = TargetStore->getFunction();
+ EXPECT_NE(F, OutlinedFn);
+
+ EXPECT_TRUE(OutlinedFn->hasWeakODRLinkage());
+ // Account for the "implicit" first argument.
+ EXPECT_EQ(OutlinedFn->getName(), "__omp_offloading_1_2_parent_l3");
+ EXPECT_EQ(OutlinedFn->arg_size(), 2U);
+ EXPECT_TRUE(OutlinedFn->getArg(1)->getType()->isPointerTy());
+
+ // Check entry block, to see if we have raised our alloca
+ // from the body to the entry block.
+ auto &EntryBlock = OutlinedFn->getEntryBlock();
+
+ // Check that we have moved our alloca created in the
+ // BodyGenCB function, to the top of the function.
+ Instruction *Alloca1 = EntryBlock.getFirstNonPHI();
+ EXPECT_NE(Alloca1, nullptr);
+ EXPECT_TRUE(isa<AllocaInst>(Alloca1));
+ EXPECT_EQ(Alloca1, RaiseAlloca);
+
+ // Verify we have not altered the rest of the function
+ // inappropriately with our alloca movement.
+ auto *Alloca2 = Alloca1->getNextNode();
+ EXPECT_TRUE(isa<AllocaInst>(Alloca2));
+ auto *Store2 = Alloca2->getNextNode();
+ EXPECT_TRUE(isa<StoreInst>(Store2));
+
+ auto *InitCall = dyn_cast<CallInst>(Store2->getNextNode());
+ EXPECT_NE(InitCall, nullptr);
+ EXPECT_EQ(InitCall->getCalledFunction()->getName(), "__kmpc_target_init");
+ EXPECT_EQ(InitCall->arg_size(), 2U);
+ EXPECT_TRUE(isa<GlobalVariable>(InitCall->getArgOperand(0)));
+ auto *KernelEnvGV = cast<GlobalVariable>(InitCall->getArgOperand(0));
+ EXPECT_TRUE(isa<ConstantStruct>(KernelEnvGV->getInitializer()));
+ auto *KernelEnvC = cast<ConstantStruct>(KernelEnvGV->getInitializer());
+ EXPECT_TRUE(isa<ConstantStruct>(KernelEnvC->getAggregateElement(0U)));
+ auto *ConfigC = cast<ConstantStruct>(KernelEnvC->getAggregateElement(0U));
+ EXPECT_EQ(ConfigC->getAggregateElement(0U),
+ ConstantInt::get(Type::getInt8Ty(Ctx), true));
+ EXPECT_EQ(ConfigC->getAggregateElement(1U),
+ ConstantInt::get(Type::getInt8Ty(Ctx), true));
+ EXPECT_EQ(ConfigC->getAggregateElement(2U),
+ ConstantInt::get(Type::getInt8Ty(Ctx), OMP_TGT_EXEC_MODE_GENERIC));
+
+ auto *EntryBlockBranch = EntryBlock.getTerminator();
+ EXPECT_NE(EntryBlockBranch, nullptr);
+ EXPECT_EQ(EntryBlockBranch->getNumSuccessors(), 2U);
+
+ // Check user code block
+ auto *UserCodeBlock = EntryBlockBranch->getSuccessor(0);
+ EXPECT_EQ(UserCodeBlock->getName(), "user_code.entry");
+ auto *Load1 = UserCodeBlock->getFirstNonPHI();
+ EXPECT_TRUE(isa<LoadInst>(Load1));
+ auto *Load2 = Load1->getNextNode();
+ EXPECT_TRUE(isa<LoadInst>(Load2));
+ EXPECT_EQ(Load2, Value);
+ EXPECT_EQ(Load2->getNextNode(), TargetStore);
+ auto *Deinit = TargetStore->getNextNode();
+ EXPECT_NE(Deinit, nullptr);
+
+ auto *DeinitCall = dyn_cast<CallInst>(Deinit);
+ EXPECT_NE(DeinitCall, nullptr);
+ EXPECT_EQ(DeinitCall->getCalledFunction()->getName(), "__kmpc_target_deinit");
+ EXPECT_EQ(DeinitCall->arg_size(), 0U);
+
+ EXPECT_TRUE(isa<ReturnInst>(DeinitCall->getNextNode()));
+
+ // Check exit block
+ auto *ExitBlock = EntryBlockBranch->getSuccessor(1);
+ EXPECT_EQ(ExitBlock->getName(), "worker.exit");
+ EXPECT_TRUE(isa<ReturnInst>(ExitBlock->getFirstNonPHI()));
+}
+
TEST_F(OpenMPIRBuilderTest, CreateTask) {
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
OpenMPIRBuilder OMPBuilder(*M);