blob: 3c960c431b5b19cccb8b4859aedc62bcea7d92ba [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);
107 OMPBuilder.setCancellationBlock(CBB);
108
109 IRBuilder<> Builder(BB);
110
111 OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
112 auto NewIP = OMPBuilder.CreateBarrier(Loc, OMPD_for);
113 Builder.restoreIP(NewIP);
114 EXPECT_FALSE(M->global_empty());
115 EXPECT_EQ(M->size(), 3U);
116 EXPECT_EQ(F->size(), 3U);
117 EXPECT_EQ(BB->size(), 4U);
118
119 CallInst *GTID = dyn_cast<CallInst>(&BB->front());
120 EXPECT_NE(GTID, nullptr);
121 EXPECT_EQ(GTID->getNumArgOperands(), 1U);
122 EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
123 EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
124 EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
125
126 CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
127 EXPECT_NE(Barrier, nullptr);
128 EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
129 EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
130 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
131 EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
132 EXPECT_EQ(Barrier->getNumUses(), 1U);
133 Instruction *BarrierBBTI = Barrier->getParent()->getTerminator();
134 EXPECT_EQ(BarrierBBTI->getNumSuccessors(), 2U);
135 EXPECT_EQ(BarrierBBTI->getSuccessor(0), NewIP.getBlock());
136 EXPECT_EQ(BarrierBBTI->getSuccessor(1), CBB);
137
138 EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
139
140 Builder.CreateUnreachable();
141 EXPECT_FALSE(verifyModule(*M));
142}
143
144TEST_F(OpenMPIRBuilderTest, DbgLoc) {
145 OpenMPIRBuilder OMPBuilder(*M);
146 OMPBuilder.initialize();
147 F->setName("func");
148
149 IRBuilder<> Builder(BB);
150
151 OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
152 OMPBuilder.CreateBarrier(Loc, OMPD_for);
153 CallInst *GTID = dyn_cast<CallInst>(&BB->front());
154 CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
155 EXPECT_EQ(GTID->getDebugLoc(), DL);
156 EXPECT_EQ(Barrier->getDebugLoc(), DL);
157 EXPECT_TRUE(isa<GlobalVariable>(Barrier->getOperand(0)));
158 if (!isa<GlobalVariable>(Barrier->getOperand(0)))
159 return;
160 GlobalVariable *Ident = cast<GlobalVariable>(Barrier->getOperand(0));
161 EXPECT_TRUE(Ident->hasInitializer());
162 if (!Ident->hasInitializer())
163 return;
164 Constant *Initializer = Ident->getInitializer();
165 EXPECT_TRUE(
166 isa<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts()));
167 GlobalVariable *SrcStrGlob =
168 cast<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts());
169 if (!SrcStrGlob)
170 return;
171 EXPECT_TRUE(isa<ConstantDataArray>(SrcStrGlob->getInitializer()));
172 ConstantDataArray *SrcSrc =
173 dyn_cast<ConstantDataArray>(SrcStrGlob->getInitializer());
174 if (!SrcSrc)
175 return;
176 EXPECT_EQ(SrcSrc->getAsCString(), ";test.dbg;foo;3;7;;");
177}
178} // namespace