diff options
author | Shraiysh Vaishay <Shraiysh.Vaishay@amd.com> | 2022-03-21 15:38:45 +0530 |
---|---|---|
committer | Shraiysh Vaishay <Shraiysh.Vaishay@amd.com> | 2022-03-21 16:19:43 +0530 |
commit | 423e3edc271242f65f5fba9fc1b25bd429ef4092 (patch) | |
tree | 60085fe4f5e360f380c5eb218356f28abdbc91e3 /llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp | |
parent | 65cf64307382ef13c8ae475680e3748c70259197 (diff) | |
download | llvm-423e3edc271242f65f5fba9fc1b25bd429ef4092.zip llvm-423e3edc271242f65f5fba9fc1b25bd429ef4092.tar.gz llvm-423e3edc271242f65f5fba9fc1b25bd429ef4092.tar.bz2 |
[OpenMP][IRBuilder] Fix emitAtomicUpdate conditions
This patch fixes the condition for emitting atomic update using
`atomicrmw` instruction or compare-exchange loop.
Reviewed By: ftynse
Differential Revision: https://reviews.llvm.org/D121546
Diffstat (limited to 'llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp')
-rw-r--r-- | llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp index b01507c..7e9e92f 100644 --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -3167,6 +3167,73 @@ TEST_F(OpenMPIRBuilderTest, OMPAtomicUpdateFloat) { EXPECT_FALSE(verifyModule(*M, &errs())); } +TEST_F(OpenMPIRBuilderTest, OMPAtomicUpdateIntr) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.initialize(); + F->setName("func"); + IRBuilder<> Builder(BB); + + OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); + + Type *IntTy = Type::getInt32Ty(M->getContext()); + AllocaInst *XVal = Builder.CreateAlloca(IntTy); + XVal->setName("AtomicVar"); + Builder.CreateStore(ConstantInt::get(Type::getInt32Ty(Ctx), 0), XVal); + OpenMPIRBuilder::AtomicOpValue X = {XVal, IntTy, false, false}; + AtomicOrdering AO = AtomicOrdering::Monotonic; + Constant *ConstVal = ConstantInt::get(Type::getInt32Ty(Ctx), 1); + Value *Expr = ConstantInt::get(Type::getInt32Ty(Ctx), 1); + AtomicRMWInst::BinOp RMWOp = AtomicRMWInst::UMax; + bool IsXLHSInRHSPart = false; + + BasicBlock *EntryBB = BB; + OpenMPIRBuilder::InsertPointTy AllocaIP(EntryBB, + EntryBB->getFirstInsertionPt()); + Value *Sub = nullptr; + + auto UpdateOp = [&](Value *Atomic, IRBuilder<> &IRB) { + Sub = IRB.CreateSub(ConstVal, Atomic); + return Sub; + }; + Builder.restoreIP(OMPBuilder.createAtomicUpdate( + Builder, AllocaIP, X, Expr, AO, RMWOp, UpdateOp, IsXLHSInRHSPart)); + BasicBlock *ContBB = EntryBB->getSingleSuccessor(); + BranchInst *ContTI = dyn_cast<BranchInst>(ContBB->getTerminator()); + EXPECT_NE(ContTI, nullptr); + BasicBlock *EndBB = ContTI->getSuccessor(0); + EXPECT_TRUE(ContTI->isConditional()); + EXPECT_EQ(ContTI->getSuccessor(1), ContBB); + EXPECT_NE(EndBB, nullptr); + + PHINode *Phi = dyn_cast<PHINode>(&ContBB->front()); + EXPECT_NE(Phi, nullptr); + EXPECT_EQ(Phi->getNumIncomingValues(), 2U); + EXPECT_EQ(Phi->getIncomingBlock(0), EntryBB); + EXPECT_EQ(Phi->getIncomingBlock(1), ContBB); + + EXPECT_EQ(Sub->getNumUses(), 1U); + StoreInst *St = dyn_cast<StoreInst>(Sub->user_back()); + AllocaInst *UpdateTemp = dyn_cast<AllocaInst>(St->getPointerOperand()); + + ExtractValueInst *ExVI1 = + dyn_cast<ExtractValueInst>(Phi->getIncomingValueForBlock(ContBB)); + EXPECT_NE(ExVI1, nullptr); + AtomicCmpXchgInst *CmpExchg = + dyn_cast<AtomicCmpXchgInst>(ExVI1->getAggregateOperand()); + EXPECT_NE(CmpExchg, nullptr); + EXPECT_EQ(CmpExchg->getPointerOperand(), XVal); + EXPECT_EQ(CmpExchg->getCompareOperand(), Phi); + EXPECT_EQ(CmpExchg->getSuccessOrdering(), AtomicOrdering::Monotonic); + + LoadInst *Ld = dyn_cast<LoadInst>(CmpExchg->getNewValOperand()); + EXPECT_NE(Ld, nullptr); + EXPECT_EQ(UpdateTemp, Ld->getPointerOperand()); + + Builder.CreateRetVoid(); + OMPBuilder.finalize(); + EXPECT_FALSE(verifyModule(*M, &errs())); +} + TEST_F(OpenMPIRBuilderTest, OMPAtomicCapture) { OpenMPIRBuilder OMPBuilder(*M); OMPBuilder.initialize(); |