blob: 39dd83232d9aae3b2e0b86712e7c4b4936a7d4c3 [file] [log] [blame]
Johannes Doerfertd23c6142019-11-05 18:57:44 -06001//===- llvm/unittest/IR/OpenMPIRBuilderTest.cpp - OpenMPIRBuilder tests ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
10#include "llvm/IR/BasicBlock.h"
11#include "llvm/IR/DIBuilder.h"
12#include "llvm/IR/Function.h"
13#include "llvm/IR/LLVMContext.h"
14#include "llvm/IR/Module.h"
15#include "llvm/Frontend/OpenMP/OMPConstants.h"
16#include "llvm/IR/Verifier.h"
17#include "gtest/gtest.h"
18
19using namespace llvm;
20using namespace omp;
21using namespace types;
22
23namespace {
24
25class OpenMPIRBuilderTest : public testing::Test {
26protected:
27 void SetUp() override {
28 M.reset(new Module("MyModule", Ctx));
29 FunctionType *FTy =
30 FunctionType::get(Type::getVoidTy(Ctx), {Type::getInt32Ty(Ctx)},
31 /*isVarArg=*/false);
32 F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
33 BB = BasicBlock::Create(Ctx, "", F);
34
35 DIBuilder DIB(*M);
36 auto File = DIB.createFile("test.dbg", "/");
37 auto CU =
38 DIB.createCompileUnit(dwarf::DW_LANG_C, File, "llvm-C", true, "", 0);
39 auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
40 auto SP = DIB.createFunction(
41 CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,
42 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
43 F->setSubprogram(SP);
44 auto Scope = DIB.createLexicalBlockFile(SP, File, 0);
45 DIB.finalize();
46 DL = DebugLoc::get(3, 7, Scope);
47 }
48
49 void TearDown() override {
50 BB = nullptr;
51 M.reset();
52 uninitializeTypes();
53 }
54
55 LLVMContext Ctx;
56 std::unique_ptr<Module> M;
57 Function *F;
58 BasicBlock *BB;
59 DebugLoc DL;
60};
61
62TEST_F(OpenMPIRBuilderTest, CreateBarrier) {
63 OpenMPIRBuilder OMPBuilder(*M);
64 OMPBuilder.initialize();
65
66 IRBuilder<> Builder(BB);
67
68 OMPBuilder.CreateBarrier({IRBuilder<>::InsertPoint()}, OMPD_for);
69 EXPECT_TRUE(M->global_empty());
70 EXPECT_EQ(M->size(), 1U);
71 EXPECT_EQ(F->size(), 1U);
72 EXPECT_EQ(BB->size(), 0U);
73
74 OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
75 OMPBuilder.CreateBarrier(Loc, OMPD_for);
76 EXPECT_FALSE(M->global_empty());
77 EXPECT_EQ(M->size(), 3U);
78 EXPECT_EQ(F->size(), 1U);
79 EXPECT_EQ(BB->size(), 2U);
80
81 CallInst *GTID = dyn_cast<CallInst>(&BB->front());
82 EXPECT_NE(GTID, nullptr);
83 EXPECT_EQ(GTID->getNumArgOperands(), 1U);
84 EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
85 EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
86 EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
87
88 CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
89 EXPECT_NE(Barrier, nullptr);
90 EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
91 EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_barrier");
92 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
93 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
94
95 EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
96
97 Builder.CreateUnreachable();
98 EXPECT_FALSE(verifyModule(*M));
99}
100
101TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) {
102 OpenMPIRBuilder OMPBuilder(*M);
103 OMPBuilder.initialize();
104
105 BasicBlock *CBB = BasicBlock::Create(Ctx, "", F);
106 new UnreachableInst(Ctx, CBB);
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -0600107 auto FiniCB = [CBB](llvm::OpenMPIRBuilder::InsertPointTy IP) {
108 assert(IP.getBlock()->end() == IP.getPoint() &&
109 "Clang CG should cause non-terminated block!");
110 BranchInst::Create(CBB, IP.getBlock());
111 };
112 // Emulate an outer parallel.
113 llvm::OpenMPIRBuilder::FinalizationInfo FI(
114 {FiniCB, OMPD_parallel, /* HasCancel */ true});
115 OMPBuilder.pushFinalizationCB(std::move(FI));
Johannes Doerfertd23c6142019-11-05 18:57:44 -0600116
117 IRBuilder<> Builder(BB);
118
119 OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
120 auto NewIP = OMPBuilder.CreateBarrier(Loc, OMPD_for);
121 Builder.restoreIP(NewIP);
122 EXPECT_FALSE(M->global_empty());
123 EXPECT_EQ(M->size(), 3U);
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -0600124 EXPECT_EQ(F->size(), 4U);
Johannes Doerfertd23c6142019-11-05 18:57:44 -0600125 EXPECT_EQ(BB->size(), 4U);
126
127 CallInst *GTID = dyn_cast<CallInst>(&BB->front());
128 EXPECT_NE(GTID, nullptr);
129 EXPECT_EQ(GTID->getNumArgOperands(), 1U);
130 EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
131 EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
132 EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
133
134 CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
135 EXPECT_NE(Barrier, nullptr);
136 EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
137 EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
138 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
139 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
140 EXPECT_EQ(Barrier->getNumUses(), 1U);
141 Instruction *BarrierBBTI = Barrier->getParent()->getTerminator();
142 EXPECT_EQ(BarrierBBTI->getNumSuccessors(), 2U);
143 EXPECT_EQ(BarrierBBTI->getSuccessor(0), NewIP.getBlock());
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -0600144 EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
145 1U);
146 EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0),
147 CBB);
Johannes Doerfertd23c6142019-11-05 18:57:44 -0600148
149 EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
150
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -0600151 OMPBuilder.popFinalizationCB();
152
Johannes Doerfertd23c6142019-11-05 18:57:44 -0600153 Builder.CreateUnreachable();
154 EXPECT_FALSE(verifyModule(*M));
155}
156
157TEST_F(OpenMPIRBuilderTest, DbgLoc) {
158 OpenMPIRBuilder OMPBuilder(*M);
159 OMPBuilder.initialize();
160 F->setName("func");
161
162 IRBuilder<> Builder(BB);
163
164 OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
165 OMPBuilder.CreateBarrier(Loc, OMPD_for);
166 CallInst *GTID = dyn_cast<CallInst>(&BB->front());
167 CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
168 EXPECT_EQ(GTID->getDebugLoc(), DL);
169 EXPECT_EQ(Barrier->getDebugLoc(), DL);
170 EXPECT_TRUE(isa<GlobalVariable>(Barrier->getOperand(0)));
171 if (!isa<GlobalVariable>(Barrier->getOperand(0)))
172 return;
173 GlobalVariable *Ident = cast<GlobalVariable>(Barrier->getOperand(0));
174 EXPECT_TRUE(Ident->hasInitializer());
175 if (!Ident->hasInitializer())
176 return;
177 Constant *Initializer = Ident->getInitializer();
178 EXPECT_TRUE(
179 isa<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts()));
180 GlobalVariable *SrcStrGlob =
181 cast<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts());
182 if (!SrcStrGlob)
183 return;
184 EXPECT_TRUE(isa<ConstantDataArray>(SrcStrGlob->getInitializer()));
185 ConstantDataArray *SrcSrc =
186 dyn_cast<ConstantDataArray>(SrcStrGlob->getInitializer());
187 if (!SrcSrc)
188 return;
189 EXPECT_EQ(SrcSrc->getAsCString(), ";test.dbg;foo;3;7;;");
190}
191} // namespace