aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
diff options
context:
space:
mode:
authorLeandro Lupori <leandro.lupori@linaro.org>2024-02-28 13:33:42 -0300
committerGitHub <noreply@github.com>2024-02-28 13:33:42 -0300
commit64422cf826354ee1d586c2484ec72d66db898e75 (patch)
tree70d09b85728482c898845b140a5f6afd704cdc5d /llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
parent3fac0562f8bdf193f039945eb40c51a5e6c24de1 (diff)
downloadllvm-64422cf826354ee1d586c2484ec72d66db898e75.zip
llvm-64422cf826354ee1d586c2484ec72d66db898e75.tar.gz
llvm-64422cf826354ee1d586c2484ec72d66db898e75.tar.bz2
[llvm][mlir][OMPIRBuilder] Translate omp.single's copyprivate (#80488)
Use the new copyprivate list from omp.single to emit calls to __kmpc_copyprivate, during the creation of the single operation in OMPIRBuilder. This is patch 4 of 4, to add support for COPYPRIVATE in Flang. Original PR: https://github.com/llvm/llvm-project/pull/73128
Diffstat (limited to 'llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp')
-rw-r--r--llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp153
1 files changed, 149 insertions, 4 deletions
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index d923b25..fdbe8df 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -3327,8 +3327,8 @@ TEST_F(OpenMPIRBuilderTest, SingleDirective) {
EXPECT_NE(IPBB->end(), IP.getPoint());
};
- Builder.restoreIP(OMPBuilder.createSingle(
- Builder, BodyGenCB, FiniCB, /*IsNowait*/ false, /*DidIt*/ nullptr));
+ Builder.restoreIP(
+ OMPBuilder.createSingle(Builder, BodyGenCB, FiniCB, /*IsNowait*/ false));
Value *EntryBBTI = EntryBB->getTerminator();
EXPECT_NE(EntryBBTI, nullptr);
EXPECT_TRUE(isa<BranchInst>(EntryBBTI));
@@ -3417,8 +3417,8 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveNowait) {
EXPECT_NE(IPBB->end(), IP.getPoint());
};
- Builder.restoreIP(OMPBuilder.createSingle(
- Builder, BodyGenCB, FiniCB, /*IsNowait*/ true, /*DidIt*/ nullptr));
+ Builder.restoreIP(
+ OMPBuilder.createSingle(Builder, BodyGenCB, FiniCB, /*IsNowait*/ true));
Value *EntryBBTI = EntryBB->getTerminator();
EXPECT_NE(EntryBBTI, nullptr);
EXPECT_TRUE(isa<BranchInst>(EntryBBTI));
@@ -3464,6 +3464,151 @@ TEST_F(OpenMPIRBuilderTest, SingleDirectiveNowait) {
EXPECT_EQ(ExitBarrier, nullptr);
}
+// Helper class to check each instruction of a BB.
+class BBInstIter {
+ BasicBlock *BB;
+ BasicBlock::iterator BBI;
+
+public:
+ BBInstIter(BasicBlock *BB) : BB(BB), BBI(BB->begin()) {}
+
+ bool hasNext() const { return BBI != BB->end(); }
+
+ template <typename InstTy> InstTy *next() {
+ if (!hasNext())
+ return nullptr;
+ Instruction *Cur = &*BBI++;
+ if (!isa<InstTy>(Cur))
+ return nullptr;
+ return cast<InstTy>(Cur);
+ }
+};
+
+TEST_F(OpenMPIRBuilderTest, SingleDirectiveCopyPrivate) {
+ using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
+ OpenMPIRBuilder OMPBuilder(*M);
+ OMPBuilder.initialize();
+ F->setName("func");
+ IRBuilder<> Builder(BB);
+
+ OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
+
+ AllocaInst *PrivAI = nullptr;
+
+ BasicBlock *EntryBB = nullptr;
+ BasicBlock *ThenBB = nullptr;
+
+ Value *CPVar = Builder.CreateAlloca(F->arg_begin()->getType());
+ Builder.CreateStore(F->arg_begin(), CPVar);
+
+ FunctionType *CopyFuncTy = FunctionType::get(
+ Builder.getVoidTy(), {Builder.getPtrTy(), Builder.getPtrTy()}, false);
+ Function *CopyFunc =
+ Function::Create(CopyFuncTy, Function::PrivateLinkage, "copy_var", *M);
+
+ auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
+ if (AllocaIP.isSet())
+ Builder.restoreIP(AllocaIP);
+ else
+ Builder.SetInsertPoint(&*(F->getEntryBlock().getFirstInsertionPt()));
+ PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
+ Builder.CreateStore(F->arg_begin(), PrivAI);
+
+ llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
+ llvm::Instruction *CodeGenIPInst = &*CodeGenIP.getPoint();
+ EXPECT_EQ(CodeGenIPBB->getTerminator(), CodeGenIPInst);
+
+ Builder.restoreIP(CodeGenIP);
+
+ // collect some info for checks later
+ ThenBB = Builder.GetInsertBlock();
+ EntryBB = ThenBB->getUniquePredecessor();
+
+ // simple instructions for body
+ Value *PrivLoad =
+ Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI, "local.use");
+ Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
+ };
+
+ auto FiniCB = [&](InsertPointTy IP) {
+ BasicBlock *IPBB = IP.getBlock();
+ // IP must be before the unconditional branch to ExitBB
+ EXPECT_NE(IPBB->end(), IP.getPoint());
+ };
+
+ Builder.restoreIP(OMPBuilder.createSingle(Builder, BodyGenCB, FiniCB,
+ /*IsNowait*/ false, {CPVar},
+ {CopyFunc}));
+ Value *EntryBBTI = EntryBB->getTerminator();
+ EXPECT_NE(EntryBBTI, nullptr);
+ EXPECT_TRUE(isa<BranchInst>(EntryBBTI));
+ BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator());
+ EXPECT_TRUE(EntryBr->isConditional());
+ EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB);
+ BasicBlock *ExitBB = ThenBB->getUniqueSuccessor();
+ EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB);
+
+ CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition());
+ EXPECT_TRUE(isa<CallInst>(CondInst->getOperand(0)));
+
+ CallInst *SingleEntryCI = cast<CallInst>(CondInst->getOperand(0));
+ EXPECT_EQ(SingleEntryCI->arg_size(), 2U);
+ EXPECT_EQ(SingleEntryCI->getCalledFunction()->getName(), "__kmpc_single");
+ EXPECT_TRUE(isa<GlobalVariable>(SingleEntryCI->getArgOperand(0)));
+
+ // check ThenBB
+ BBInstIter ThenBBI(ThenBB);
+ // load PrivAI
+ auto *PrivLI = ThenBBI.next<LoadInst>();
+ EXPECT_NE(PrivLI, nullptr);
+ EXPECT_EQ(PrivLI->getPointerOperand(), PrivAI);
+ // icmp
+ EXPECT_TRUE(ThenBBI.next<ICmpInst>());
+ // store 1, DidIt
+ auto *DidItSI = ThenBBI.next<StoreInst>();
+ EXPECT_NE(DidItSI, nullptr);
+ EXPECT_EQ(DidItSI->getValueOperand(),
+ ConstantInt::get(Type::getInt32Ty(Ctx), 1));
+ Value *DidIt = DidItSI->getPointerOperand();
+ // call __kmpc_end_single
+ auto *SingleEndCI = ThenBBI.next<CallInst>();
+ EXPECT_NE(SingleEndCI, nullptr);
+ EXPECT_EQ(SingleEndCI->getCalledFunction()->getName(), "__kmpc_end_single");
+ EXPECT_EQ(SingleEndCI->arg_size(), 2U);
+ EXPECT_TRUE(isa<GlobalVariable>(SingleEndCI->getArgOperand(0)));
+ EXPECT_EQ(SingleEndCI->getArgOperand(1), SingleEntryCI->getArgOperand(1));
+ // br ExitBB
+ auto *ExitBBBI = ThenBBI.next<BranchInst>();
+ EXPECT_NE(ExitBBBI, nullptr);
+ EXPECT_TRUE(ExitBBBI->isUnconditional());
+ EXPECT_EQ(ExitBBBI->getOperand(0), ExitBB);
+ EXPECT_FALSE(ThenBBI.hasNext());
+
+ // check ExitBB
+ BBInstIter ExitBBI(ExitBB);
+ // call __kmpc_global_thread_num
+ auto *ThreadNumCI = ExitBBI.next<CallInst>();
+ EXPECT_NE(ThreadNumCI, nullptr);
+ EXPECT_EQ(ThreadNumCI->getCalledFunction()->getName(),
+ "__kmpc_global_thread_num");
+ // load DidIt
+ auto *DidItLI = ExitBBI.next<LoadInst>();
+ EXPECT_NE(DidItLI, nullptr);
+ EXPECT_EQ(DidItLI->getPointerOperand(), DidIt);
+ // call __kmpc_copyprivate
+ auto *CopyPrivateCI = ExitBBI.next<CallInst>();
+ EXPECT_NE(CopyPrivateCI, nullptr);
+ EXPECT_EQ(CopyPrivateCI->arg_size(), 6U);
+ EXPECT_TRUE(isa<AllocaInst>(CopyPrivateCI->getArgOperand(3)));
+ EXPECT_EQ(CopyPrivateCI->getArgOperand(3), CPVar);
+ EXPECT_TRUE(isa<Function>(CopyPrivateCI->getArgOperand(4)));
+ EXPECT_EQ(CopyPrivateCI->getArgOperand(4), CopyFunc);
+ EXPECT_TRUE(isa<LoadInst>(CopyPrivateCI->getArgOperand(5)));
+ DidItLI = cast<LoadInst>(CopyPrivateCI->getArgOperand(5));
+ EXPECT_EQ(DidItLI->getOperand(0), DidIt);
+ EXPECT_FALSE(ExitBBI.hasNext());
+}
+
TEST_F(OpenMPIRBuilderTest, OMPAtomicReadFlt) {
OpenMPIRBuilder OMPBuilder(*M);
OMPBuilder.initialize();