1 //===- 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/OMPConstants.h"
10 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/DIBuilder.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/InstIterator.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Verifier.h"
18 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 using namespace omp;
23 
24 namespace {
25 
26 /// Create an instruction that uses the values in \p Values. We use "printf"
27 /// just because it is often used for this purpose in test code, but it is never
28 /// executed here.
29 static CallInst *createPrintfCall(IRBuilder<> &Builder, StringRef FormatStr,
30                                   ArrayRef<Value *> Values) {
31   Module *M = Builder.GetInsertBlock()->getParent()->getParent();
32 
33   GlobalVariable *GV = Builder.CreateGlobalString(FormatStr, "", 0, M);
34   Constant *Zero = ConstantInt::get(Type::getInt32Ty(M->getContext()), 0);
35   Constant *Indices[] = {Zero, Zero};
36   Constant *FormatStrConst =
37       ConstantExpr::getInBoundsGetElementPtr(GV->getValueType(), GV, Indices);
38 
39   Function *PrintfDecl = M->getFunction("printf");
40   if (!PrintfDecl) {
41     GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
42     FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), true);
43     PrintfDecl = Function::Create(Ty, Linkage, "printf", M);
44   }
45 
46   SmallVector<Value *, 4> Args;
47   Args.push_back(FormatStrConst);
48   Args.append(Values.begin(), Values.end());
49   return Builder.CreateCall(PrintfDecl, Args);
50 }
51 
52 /// Verify that blocks in \p RefOrder are corresponds to the depth-first visit
53 /// order the control flow of \p F.
54 ///
55 /// This is an easy way to verify the branching structure of the CFG without
56 /// checking every branch instruction individually. For the CFG of a
57 /// CanonicalLoopInfo, the Cond BB's terminating branch's first edge is entering
58 /// the body, i.e. the DFS order corresponds to the execution order with one
59 /// loop iteration.
60 static testing::AssertionResult
61 verifyDFSOrder(Function *F, ArrayRef<BasicBlock *> RefOrder) {
62   ArrayRef<BasicBlock *>::iterator It = RefOrder.begin();
63   ArrayRef<BasicBlock *>::iterator E = RefOrder.end();
64 
65   df_iterator_default_set<BasicBlock *, 16> Visited;
66   auto DFS = llvm::depth_first_ext(&F->getEntryBlock(), Visited);
67 
68   BasicBlock *Prev = nullptr;
69   for (BasicBlock *BB : DFS) {
70     if (It != E && BB == *It) {
71       Prev = *It;
72       ++It;
73     }
74   }
75 
76   if (It == E)
77     return testing::AssertionSuccess();
78   if (!Prev)
79     return testing::AssertionFailure()
80            << "Did not find " << (*It)->getName() << " in control flow";
81   return testing::AssertionFailure()
82          << "Expected " << Prev->getName() << " before " << (*It)->getName()
83          << " in control flow";
84 }
85 
86 /// Verify that blocks in \p RefOrder are in the same relative order in the
87 /// linked lists of blocks in \p F. The linked list may contain additional
88 /// blocks in-between.
89 ///
90 /// While the order in the linked list is not relevant for semantics, keeping
91 /// the order roughly in execution order makes its printout easier to read.
92 static testing::AssertionResult
93 verifyListOrder(Function *F, ArrayRef<BasicBlock *> RefOrder) {
94   ArrayRef<BasicBlock *>::iterator It = RefOrder.begin();
95   ArrayRef<BasicBlock *>::iterator E = RefOrder.end();
96 
97   BasicBlock *Prev = nullptr;
98   for (BasicBlock &BB : *F) {
99     if (It != E && &BB == *It) {
100       Prev = *It;
101       ++It;
102     }
103   }
104 
105   if (It == E)
106     return testing::AssertionSuccess();
107   if (!Prev)
108     return testing::AssertionFailure() << "Did not find " << (*It)->getName()
109                                        << " in function " << F->getName();
110   return testing::AssertionFailure()
111          << "Expected " << Prev->getName() << " before " << (*It)->getName()
112          << " in function " << F->getName();
113 }
114 
115 class OpenMPIRBuilderTest : public testing::Test {
116 protected:
117   void SetUp() override {
118     M.reset(new Module("MyModule", Ctx));
119     FunctionType *FTy =
120         FunctionType::get(Type::getVoidTy(Ctx), {Type::getInt32Ty(Ctx)},
121                           /*isVarArg=*/false);
122     F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
123     BB = BasicBlock::Create(Ctx, "", F);
124 
125     DIBuilder DIB(*M);
126     auto File = DIB.createFile("test.dbg", "/src", llvm::None,
127                                Optional<StringRef>("/src/test.dbg"));
128     auto CU =
129         DIB.createCompileUnit(dwarf::DW_LANG_C, File, "llvm-C", true, "", 0);
130     auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
131     auto SP = DIB.createFunction(
132         CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,
133         DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
134     F->setSubprogram(SP);
135     auto Scope = DIB.createLexicalBlockFile(SP, File, 0);
136     DIB.finalize();
137     DL = DILocation::get(Ctx, 3, 7, Scope);
138   }
139 
140   void TearDown() override {
141     BB = nullptr;
142     M.reset();
143   }
144 
145   LLVMContext Ctx;
146   std::unique_ptr<Module> M;
147   Function *F;
148   BasicBlock *BB;
149   DebugLoc DL;
150 };
151 
152 // Returns the value stored in the given allocation. Returns null if the given
153 // value is not a result of an allocation, if no value is stored or if there is
154 // more than one store.
155 static Value *findStoredValue(Value *AllocaValue) {
156   Instruction *Alloca = dyn_cast<AllocaInst>(AllocaValue);
157   if (!Alloca)
158     return nullptr;
159   StoreInst *Store = nullptr;
160   for (Use &U : Alloca->uses()) {
161     if (auto *CandidateStore = dyn_cast<StoreInst>(U.getUser())) {
162       EXPECT_EQ(Store, nullptr);
163       Store = CandidateStore;
164     }
165   }
166   if (!Store)
167     return nullptr;
168   return Store->getValueOperand();
169 }
170 
171 TEST_F(OpenMPIRBuilderTest, CreateBarrier) {
172   OpenMPIRBuilder OMPBuilder(*M);
173   OMPBuilder.initialize();
174 
175   IRBuilder<> Builder(BB);
176 
177   OMPBuilder.createBarrier({IRBuilder<>::InsertPoint()}, OMPD_for);
178   EXPECT_TRUE(M->global_empty());
179   EXPECT_EQ(M->size(), 1U);
180   EXPECT_EQ(F->size(), 1U);
181   EXPECT_EQ(BB->size(), 0U);
182 
183   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
184   OMPBuilder.createBarrier(Loc, OMPD_for);
185   EXPECT_FALSE(M->global_empty());
186   EXPECT_EQ(M->size(), 3U);
187   EXPECT_EQ(F->size(), 1U);
188   EXPECT_EQ(BB->size(), 2U);
189 
190   CallInst *GTID = dyn_cast<CallInst>(&BB->front());
191   EXPECT_NE(GTID, nullptr);
192   EXPECT_EQ(GTID->getNumArgOperands(), 1U);
193   EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
194   EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
195   EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
196 
197   CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
198   EXPECT_NE(Barrier, nullptr);
199   EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
200   EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_barrier");
201   EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
202   EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
203 
204   EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
205 
206   Builder.CreateUnreachable();
207   EXPECT_FALSE(verifyModule(*M, &errs()));
208 }
209 
210 TEST_F(OpenMPIRBuilderTest, CreateCancel) {
211   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
212   OpenMPIRBuilder OMPBuilder(*M);
213   OMPBuilder.initialize();
214 
215   BasicBlock *CBB = BasicBlock::Create(Ctx, "", F);
216   new UnreachableInst(Ctx, CBB);
217   auto FiniCB = [&](InsertPointTy IP) {
218     ASSERT_NE(IP.getBlock(), nullptr);
219     ASSERT_EQ(IP.getBlock()->end(), IP.getPoint());
220     BranchInst::Create(CBB, IP.getBlock());
221   };
222   OMPBuilder.pushFinalizationCB({FiniCB, OMPD_parallel, true});
223 
224   IRBuilder<> Builder(BB);
225 
226   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
227   auto NewIP = OMPBuilder.createCancel(Loc, nullptr, OMPD_parallel);
228   Builder.restoreIP(NewIP);
229   EXPECT_FALSE(M->global_empty());
230   EXPECT_EQ(M->size(), 3U);
231   EXPECT_EQ(F->size(), 4U);
232   EXPECT_EQ(BB->size(), 4U);
233 
234   CallInst *GTID = dyn_cast<CallInst>(&BB->front());
235   EXPECT_NE(GTID, nullptr);
236   EXPECT_EQ(GTID->getNumArgOperands(), 1U);
237   EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
238   EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
239   EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
240 
241   CallInst *Cancel = dyn_cast<CallInst>(GTID->getNextNode());
242   EXPECT_NE(Cancel, nullptr);
243   EXPECT_EQ(Cancel->getNumArgOperands(), 3U);
244   EXPECT_EQ(Cancel->getCalledFunction()->getName(), "__kmpc_cancel");
245   EXPECT_FALSE(Cancel->getCalledFunction()->doesNotAccessMemory());
246   EXPECT_FALSE(Cancel->getCalledFunction()->doesNotFreeMemory());
247   EXPECT_EQ(Cancel->getNumUses(), 1U);
248   Instruction *CancelBBTI = Cancel->getParent()->getTerminator();
249   EXPECT_EQ(CancelBBTI->getNumSuccessors(), 2U);
250   EXPECT_EQ(CancelBBTI->getSuccessor(0), NewIP.getBlock());
251   EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U);
252   EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
253             1U);
254   EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0),
255             CBB);
256 
257   EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID);
258 
259   OMPBuilder.popFinalizationCB();
260 
261   Builder.CreateUnreachable();
262   EXPECT_FALSE(verifyModule(*M, &errs()));
263 }
264 
265 TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) {
266   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
267   OpenMPIRBuilder OMPBuilder(*M);
268   OMPBuilder.initialize();
269 
270   BasicBlock *CBB = BasicBlock::Create(Ctx, "", F);
271   new UnreachableInst(Ctx, CBB);
272   auto FiniCB = [&](InsertPointTy IP) {
273     ASSERT_NE(IP.getBlock(), nullptr);
274     ASSERT_EQ(IP.getBlock()->end(), IP.getPoint());
275     BranchInst::Create(CBB, IP.getBlock());
276   };
277   OMPBuilder.pushFinalizationCB({FiniCB, OMPD_parallel, true});
278 
279   IRBuilder<> Builder(BB);
280 
281   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
282   auto NewIP = OMPBuilder.createCancel(Loc, Builder.getTrue(), OMPD_parallel);
283   Builder.restoreIP(NewIP);
284   EXPECT_FALSE(M->global_empty());
285   EXPECT_EQ(M->size(), 3U);
286   EXPECT_EQ(F->size(), 7U);
287   EXPECT_EQ(BB->size(), 1U);
288   ASSERT_TRUE(isa<BranchInst>(BB->getTerminator()));
289   ASSERT_EQ(BB->getTerminator()->getNumSuccessors(), 2U);
290   BB = BB->getTerminator()->getSuccessor(0);
291   EXPECT_EQ(BB->size(), 4U);
292 
293 
294   CallInst *GTID = dyn_cast<CallInst>(&BB->front());
295   EXPECT_NE(GTID, nullptr);
296   EXPECT_EQ(GTID->getNumArgOperands(), 1U);
297   EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
298   EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
299   EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
300 
301   CallInst *Cancel = dyn_cast<CallInst>(GTID->getNextNode());
302   EXPECT_NE(Cancel, nullptr);
303   EXPECT_EQ(Cancel->getNumArgOperands(), 3U);
304   EXPECT_EQ(Cancel->getCalledFunction()->getName(), "__kmpc_cancel");
305   EXPECT_FALSE(Cancel->getCalledFunction()->doesNotAccessMemory());
306   EXPECT_FALSE(Cancel->getCalledFunction()->doesNotFreeMemory());
307   EXPECT_EQ(Cancel->getNumUses(), 1U);
308   Instruction *CancelBBTI = Cancel->getParent()->getTerminator();
309   EXPECT_EQ(CancelBBTI->getNumSuccessors(), 2U);
310   EXPECT_EQ(CancelBBTI->getSuccessor(0)->size(), 1U);
311   EXPECT_EQ(CancelBBTI->getSuccessor(0)->getUniqueSuccessor(), NewIP.getBlock());
312   EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U);
313   EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
314             1U);
315   EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0),
316             CBB);
317 
318   EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID);
319 
320   OMPBuilder.popFinalizationCB();
321 
322   Builder.CreateUnreachable();
323   EXPECT_FALSE(verifyModule(*M, &errs()));
324 }
325 
326 TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) {
327   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
328   OpenMPIRBuilder OMPBuilder(*M);
329   OMPBuilder.initialize();
330 
331   BasicBlock *CBB = BasicBlock::Create(Ctx, "", F);
332   new UnreachableInst(Ctx, CBB);
333   auto FiniCB = [&](InsertPointTy IP) {
334     ASSERT_NE(IP.getBlock(), nullptr);
335     ASSERT_EQ(IP.getBlock()->end(), IP.getPoint());
336     BranchInst::Create(CBB, IP.getBlock());
337   };
338   OMPBuilder.pushFinalizationCB({FiniCB, OMPD_parallel, true});
339 
340   IRBuilder<> Builder(BB);
341 
342   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
343   auto NewIP = OMPBuilder.createBarrier(Loc, OMPD_for);
344   Builder.restoreIP(NewIP);
345   EXPECT_FALSE(M->global_empty());
346   EXPECT_EQ(M->size(), 3U);
347   EXPECT_EQ(F->size(), 4U);
348   EXPECT_EQ(BB->size(), 4U);
349 
350   CallInst *GTID = dyn_cast<CallInst>(&BB->front());
351   EXPECT_NE(GTID, nullptr);
352   EXPECT_EQ(GTID->getNumArgOperands(), 1U);
353   EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
354   EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
355   EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
356 
357   CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
358   EXPECT_NE(Barrier, nullptr);
359   EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
360   EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
361   EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
362   EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
363   EXPECT_EQ(Barrier->getNumUses(), 1U);
364   Instruction *BarrierBBTI = Barrier->getParent()->getTerminator();
365   EXPECT_EQ(BarrierBBTI->getNumSuccessors(), 2U);
366   EXPECT_EQ(BarrierBBTI->getSuccessor(0), NewIP.getBlock());
367   EXPECT_EQ(BarrierBBTI->getSuccessor(1)->size(), 1U);
368   EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
369             1U);
370   EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0),
371             CBB);
372 
373   EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
374 
375   OMPBuilder.popFinalizationCB();
376 
377   Builder.CreateUnreachable();
378   EXPECT_FALSE(verifyModule(*M, &errs()));
379 }
380 
381 TEST_F(OpenMPIRBuilderTest, DbgLoc) {
382   OpenMPIRBuilder OMPBuilder(*M);
383   OMPBuilder.initialize();
384   F->setName("func");
385 
386   IRBuilder<> Builder(BB);
387 
388   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
389   OMPBuilder.createBarrier(Loc, OMPD_for);
390   CallInst *GTID = dyn_cast<CallInst>(&BB->front());
391   CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
392   EXPECT_EQ(GTID->getDebugLoc(), DL);
393   EXPECT_EQ(Barrier->getDebugLoc(), DL);
394   EXPECT_TRUE(isa<GlobalVariable>(Barrier->getOperand(0)));
395   if (!isa<GlobalVariable>(Barrier->getOperand(0)))
396     return;
397   GlobalVariable *Ident = cast<GlobalVariable>(Barrier->getOperand(0));
398   EXPECT_TRUE(Ident->hasInitializer());
399   if (!Ident->hasInitializer())
400     return;
401   Constant *Initializer = Ident->getInitializer();
402   EXPECT_TRUE(
403       isa<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts()));
404   GlobalVariable *SrcStrGlob =
405       cast<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts());
406   if (!SrcStrGlob)
407     return;
408   EXPECT_TRUE(isa<ConstantDataArray>(SrcStrGlob->getInitializer()));
409   ConstantDataArray *SrcSrc =
410       dyn_cast<ConstantDataArray>(SrcStrGlob->getInitializer());
411   if (!SrcSrc)
412     return;
413   EXPECT_EQ(SrcSrc->getAsCString(), ";/src/test.dbg;foo;3;7;;");
414 }
415 
416 TEST_F(OpenMPIRBuilderTest, ParallelSimple) {
417   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
418   OpenMPIRBuilder OMPBuilder(*M);
419   OMPBuilder.initialize();
420   F->setName("func");
421   IRBuilder<> Builder(BB);
422 
423   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
424 
425   AllocaInst *PrivAI = nullptr;
426 
427   unsigned NumBodiesGenerated = 0;
428   unsigned NumPrivatizedVars = 0;
429   unsigned NumFinalizationPoints = 0;
430 
431   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
432                        BasicBlock &ContinuationIP) {
433     ++NumBodiesGenerated;
434 
435     Builder.restoreIP(AllocaIP);
436     PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
437     Builder.CreateStore(F->arg_begin(), PrivAI);
438 
439     Builder.restoreIP(CodeGenIP);
440     Value *PrivLoad = Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI,
441                                          "local.use");
442     Value *Cmp = Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
443     Instruction *ThenTerm, *ElseTerm;
444     SplitBlockAndInsertIfThenElse(Cmp, CodeGenIP.getBlock()->getTerminator(),
445                                   &ThenTerm, &ElseTerm);
446 
447     Builder.SetInsertPoint(ThenTerm);
448     Builder.CreateBr(&ContinuationIP);
449     ThenTerm->eraseFromParent();
450   };
451 
452   auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
453                     Value &Orig, Value &Inner,
454                     Value *&ReplacementValue) -> InsertPointTy {
455     ++NumPrivatizedVars;
456 
457     if (!isa<AllocaInst>(Orig)) {
458       EXPECT_EQ(&Orig, F->arg_begin());
459       ReplacementValue = &Inner;
460       return CodeGenIP;
461     }
462 
463     // Since the original value is an allocation, it has a pointer type and
464     // therefore no additional wrapping should happen.
465     EXPECT_EQ(&Orig, &Inner);
466 
467     // Trivial copy (=firstprivate).
468     Builder.restoreIP(AllocaIP);
469     Type *VTy = Inner.getType()->getPointerElementType();
470     Value *V = Builder.CreateLoad(VTy, &Inner, Orig.getName() + ".reload");
471     ReplacementValue = Builder.CreateAlloca(VTy, 0, Orig.getName() + ".copy");
472     Builder.restoreIP(CodeGenIP);
473     Builder.CreateStore(V, ReplacementValue);
474     return CodeGenIP;
475   };
476 
477   auto FiniCB = [&](InsertPointTy CodeGenIP) { ++NumFinalizationPoints; };
478 
479   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
480                                     F->getEntryBlock().getFirstInsertionPt());
481   IRBuilder<>::InsertPoint AfterIP =
482       OMPBuilder.createParallel(Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB,
483                                 nullptr, nullptr, OMP_PROC_BIND_default, false);
484   EXPECT_EQ(NumBodiesGenerated, 1U);
485   EXPECT_EQ(NumPrivatizedVars, 1U);
486   EXPECT_EQ(NumFinalizationPoints, 1U);
487 
488   Builder.restoreIP(AfterIP);
489   Builder.CreateRetVoid();
490 
491   OMPBuilder.finalize();
492 
493   EXPECT_NE(PrivAI, nullptr);
494   Function *OutlinedFn = PrivAI->getFunction();
495   EXPECT_NE(F, OutlinedFn);
496   EXPECT_FALSE(verifyModule(*M, &errs()));
497   EXPECT_TRUE(OutlinedFn->hasFnAttribute(Attribute::NoUnwind));
498   EXPECT_TRUE(OutlinedFn->hasFnAttribute(Attribute::NoRecurse));
499   EXPECT_TRUE(OutlinedFn->hasParamAttribute(0, Attribute::NoAlias));
500   EXPECT_TRUE(OutlinedFn->hasParamAttribute(1, Attribute::NoAlias));
501 
502   EXPECT_TRUE(OutlinedFn->hasInternalLinkage());
503   EXPECT_EQ(OutlinedFn->arg_size(), 3U);
504 
505   EXPECT_EQ(&OutlinedFn->getEntryBlock(), PrivAI->getParent());
506   EXPECT_EQ(OutlinedFn->getNumUses(), 1U);
507   User *Usr = OutlinedFn->user_back();
508   ASSERT_TRUE(isa<ConstantExpr>(Usr));
509   CallInst *ForkCI = dyn_cast<CallInst>(Usr->user_back());
510   ASSERT_NE(ForkCI, nullptr);
511 
512   EXPECT_EQ(ForkCI->getCalledFunction()->getName(), "__kmpc_fork_call");
513   EXPECT_EQ(ForkCI->getNumArgOperands(), 4U);
514   EXPECT_TRUE(isa<GlobalVariable>(ForkCI->getArgOperand(0)));
515   EXPECT_EQ(ForkCI->getArgOperand(1),
516             ConstantInt::get(Type::getInt32Ty(Ctx), 1U));
517   EXPECT_EQ(ForkCI->getArgOperand(2), Usr);
518   EXPECT_EQ(findStoredValue(ForkCI->getArgOperand(3)), F->arg_begin());
519 }
520 
521 TEST_F(OpenMPIRBuilderTest, ParallelNested) {
522   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
523   OpenMPIRBuilder OMPBuilder(*M);
524   OMPBuilder.initialize();
525   F->setName("func");
526   IRBuilder<> Builder(BB);
527 
528   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
529 
530   unsigned NumInnerBodiesGenerated = 0;
531   unsigned NumOuterBodiesGenerated = 0;
532   unsigned NumFinalizationPoints = 0;
533 
534   auto InnerBodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
535                             BasicBlock &ContinuationIP) {
536     ++NumInnerBodiesGenerated;
537   };
538 
539   auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
540                     Value &Orig, Value &Inner,
541                     Value *&ReplacementValue) -> InsertPointTy {
542     // Trivial copy (=firstprivate).
543     Builder.restoreIP(AllocaIP);
544     Type *VTy = Inner.getType()->getPointerElementType();
545     Value *V = Builder.CreateLoad(VTy, &Inner, Orig.getName() + ".reload");
546     ReplacementValue = Builder.CreateAlloca(VTy, 0, Orig.getName() + ".copy");
547     Builder.restoreIP(CodeGenIP);
548     Builder.CreateStore(V, ReplacementValue);
549     return CodeGenIP;
550   };
551 
552   auto FiniCB = [&](InsertPointTy CodeGenIP) { ++NumFinalizationPoints; };
553 
554   auto OuterBodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
555                             BasicBlock &ContinuationIP) {
556     ++NumOuterBodiesGenerated;
557     Builder.restoreIP(CodeGenIP);
558     BasicBlock *CGBB = CodeGenIP.getBlock();
559     BasicBlock *NewBB = SplitBlock(CGBB, &*CodeGenIP.getPoint());
560     CGBB->getTerminator()->eraseFromParent();
561     ;
562 
563     IRBuilder<>::InsertPoint AfterIP = OMPBuilder.createParallel(
564         InsertPointTy(CGBB, CGBB->end()), AllocaIP, InnerBodyGenCB, PrivCB,
565         FiniCB, nullptr, nullptr, OMP_PROC_BIND_default, false);
566 
567     Builder.restoreIP(AfterIP);
568     Builder.CreateBr(NewBB);
569   };
570 
571   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
572                                     F->getEntryBlock().getFirstInsertionPt());
573   IRBuilder<>::InsertPoint AfterIP =
574       OMPBuilder.createParallel(Loc, AllocaIP, OuterBodyGenCB, PrivCB, FiniCB,
575                                 nullptr, nullptr, OMP_PROC_BIND_default, false);
576 
577   EXPECT_EQ(NumInnerBodiesGenerated, 1U);
578   EXPECT_EQ(NumOuterBodiesGenerated, 1U);
579   EXPECT_EQ(NumFinalizationPoints, 2U);
580 
581   Builder.restoreIP(AfterIP);
582   Builder.CreateRetVoid();
583 
584   OMPBuilder.finalize();
585 
586   EXPECT_EQ(M->size(), 5U);
587   for (Function &OutlinedFn : *M) {
588     if (F == &OutlinedFn || OutlinedFn.isDeclaration())
589       continue;
590     EXPECT_FALSE(verifyModule(*M, &errs()));
591     EXPECT_TRUE(OutlinedFn.hasFnAttribute(Attribute::NoUnwind));
592     EXPECT_TRUE(OutlinedFn.hasFnAttribute(Attribute::NoRecurse));
593     EXPECT_TRUE(OutlinedFn.hasParamAttribute(0, Attribute::NoAlias));
594     EXPECT_TRUE(OutlinedFn.hasParamAttribute(1, Attribute::NoAlias));
595 
596     EXPECT_TRUE(OutlinedFn.hasInternalLinkage());
597     EXPECT_EQ(OutlinedFn.arg_size(), 2U);
598 
599     EXPECT_EQ(OutlinedFn.getNumUses(), 1U);
600     User *Usr = OutlinedFn.user_back();
601     ASSERT_TRUE(isa<ConstantExpr>(Usr));
602     CallInst *ForkCI = dyn_cast<CallInst>(Usr->user_back());
603     ASSERT_NE(ForkCI, nullptr);
604 
605     EXPECT_EQ(ForkCI->getCalledFunction()->getName(), "__kmpc_fork_call");
606     EXPECT_EQ(ForkCI->getNumArgOperands(), 3U);
607     EXPECT_TRUE(isa<GlobalVariable>(ForkCI->getArgOperand(0)));
608     EXPECT_EQ(ForkCI->getArgOperand(1),
609               ConstantInt::get(Type::getInt32Ty(Ctx), 0U));
610     EXPECT_EQ(ForkCI->getArgOperand(2), Usr);
611   }
612 }
613 
614 TEST_F(OpenMPIRBuilderTest, ParallelNested2Inner) {
615   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
616   OpenMPIRBuilder OMPBuilder(*M);
617   OMPBuilder.initialize();
618   F->setName("func");
619   IRBuilder<> Builder(BB);
620 
621   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
622 
623   unsigned NumInnerBodiesGenerated = 0;
624   unsigned NumOuterBodiesGenerated = 0;
625   unsigned NumFinalizationPoints = 0;
626 
627   auto InnerBodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
628                             BasicBlock &ContinuationIP) {
629     ++NumInnerBodiesGenerated;
630   };
631 
632   auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
633                     Value &Orig, Value &Inner,
634                     Value *&ReplacementValue) -> InsertPointTy {
635     // Trivial copy (=firstprivate).
636     Builder.restoreIP(AllocaIP);
637     Type *VTy = Inner.getType()->getPointerElementType();
638     Value *V = Builder.CreateLoad(VTy, &Inner, Orig.getName() + ".reload");
639     ReplacementValue = Builder.CreateAlloca(VTy, 0, Orig.getName() + ".copy");
640     Builder.restoreIP(CodeGenIP);
641     Builder.CreateStore(V, ReplacementValue);
642     return CodeGenIP;
643   };
644 
645   auto FiniCB = [&](InsertPointTy CodeGenIP) { ++NumFinalizationPoints; };
646 
647   auto OuterBodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
648                             BasicBlock &ContinuationIP) {
649     ++NumOuterBodiesGenerated;
650     Builder.restoreIP(CodeGenIP);
651     BasicBlock *CGBB = CodeGenIP.getBlock();
652     BasicBlock *NewBB1 = SplitBlock(CGBB, &*CodeGenIP.getPoint());
653     BasicBlock *NewBB2 = SplitBlock(NewBB1, &*NewBB1->getFirstInsertionPt());
654     CGBB->getTerminator()->eraseFromParent();
655     ;
656     NewBB1->getTerminator()->eraseFromParent();
657     ;
658 
659     IRBuilder<>::InsertPoint AfterIP1 = OMPBuilder.createParallel(
660         InsertPointTy(CGBB, CGBB->end()), AllocaIP, InnerBodyGenCB, PrivCB,
661         FiniCB, nullptr, nullptr, OMP_PROC_BIND_default, false);
662 
663     Builder.restoreIP(AfterIP1);
664     Builder.CreateBr(NewBB1);
665 
666     IRBuilder<>::InsertPoint AfterIP2 = OMPBuilder.createParallel(
667         InsertPointTy(NewBB1, NewBB1->end()), AllocaIP, InnerBodyGenCB, PrivCB,
668         FiniCB, nullptr, nullptr, OMP_PROC_BIND_default, false);
669 
670     Builder.restoreIP(AfterIP2);
671     Builder.CreateBr(NewBB2);
672   };
673 
674   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
675                                     F->getEntryBlock().getFirstInsertionPt());
676   IRBuilder<>::InsertPoint AfterIP =
677       OMPBuilder.createParallel(Loc, AllocaIP, OuterBodyGenCB, PrivCB, FiniCB,
678                                 nullptr, nullptr, OMP_PROC_BIND_default, false);
679 
680   EXPECT_EQ(NumInnerBodiesGenerated, 2U);
681   EXPECT_EQ(NumOuterBodiesGenerated, 1U);
682   EXPECT_EQ(NumFinalizationPoints, 3U);
683 
684   Builder.restoreIP(AfterIP);
685   Builder.CreateRetVoid();
686 
687   OMPBuilder.finalize();
688 
689   EXPECT_EQ(M->size(), 6U);
690   for (Function &OutlinedFn : *M) {
691     if (F == &OutlinedFn || OutlinedFn.isDeclaration())
692       continue;
693     EXPECT_FALSE(verifyModule(*M, &errs()));
694     EXPECT_TRUE(OutlinedFn.hasFnAttribute(Attribute::NoUnwind));
695     EXPECT_TRUE(OutlinedFn.hasFnAttribute(Attribute::NoRecurse));
696     EXPECT_TRUE(OutlinedFn.hasParamAttribute(0, Attribute::NoAlias));
697     EXPECT_TRUE(OutlinedFn.hasParamAttribute(1, Attribute::NoAlias));
698 
699     EXPECT_TRUE(OutlinedFn.hasInternalLinkage());
700     EXPECT_EQ(OutlinedFn.arg_size(), 2U);
701 
702     unsigned NumAllocas = 0;
703     for (Instruction &I : instructions(OutlinedFn))
704       NumAllocas += isa<AllocaInst>(I);
705     EXPECT_EQ(NumAllocas, 1U);
706 
707     EXPECT_EQ(OutlinedFn.getNumUses(), 1U);
708     User *Usr = OutlinedFn.user_back();
709     ASSERT_TRUE(isa<ConstantExpr>(Usr));
710     CallInst *ForkCI = dyn_cast<CallInst>(Usr->user_back());
711     ASSERT_NE(ForkCI, nullptr);
712 
713     EXPECT_EQ(ForkCI->getCalledFunction()->getName(), "__kmpc_fork_call");
714     EXPECT_EQ(ForkCI->getNumArgOperands(), 3U);
715     EXPECT_TRUE(isa<GlobalVariable>(ForkCI->getArgOperand(0)));
716     EXPECT_EQ(ForkCI->getArgOperand(1),
717               ConstantInt::get(Type::getInt32Ty(Ctx), 0U));
718     EXPECT_EQ(ForkCI->getArgOperand(2), Usr);
719   }
720 }
721 
722 TEST_F(OpenMPIRBuilderTest, ParallelIfCond) {
723   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
724   OpenMPIRBuilder OMPBuilder(*M);
725   OMPBuilder.initialize();
726   F->setName("func");
727   IRBuilder<> Builder(BB);
728 
729   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
730 
731   AllocaInst *PrivAI = nullptr;
732 
733   unsigned NumBodiesGenerated = 0;
734   unsigned NumPrivatizedVars = 0;
735   unsigned NumFinalizationPoints = 0;
736 
737   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
738                        BasicBlock &ContinuationIP) {
739     ++NumBodiesGenerated;
740 
741     Builder.restoreIP(AllocaIP);
742     PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
743     Builder.CreateStore(F->arg_begin(), PrivAI);
744 
745     Builder.restoreIP(CodeGenIP);
746     Value *PrivLoad = Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI,
747                                          "local.use");
748     Value *Cmp = Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
749     Instruction *ThenTerm, *ElseTerm;
750     SplitBlockAndInsertIfThenElse(Cmp, CodeGenIP.getBlock()->getTerminator(),
751                                   &ThenTerm, &ElseTerm);
752 
753     Builder.SetInsertPoint(ThenTerm);
754     Builder.CreateBr(&ContinuationIP);
755     ThenTerm->eraseFromParent();
756   };
757 
758   auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
759                     Value &Orig, Value &Inner,
760                     Value *&ReplacementValue) -> InsertPointTy {
761     ++NumPrivatizedVars;
762 
763     if (!isa<AllocaInst>(Orig)) {
764       EXPECT_EQ(&Orig, F->arg_begin());
765       ReplacementValue = &Inner;
766       return CodeGenIP;
767     }
768 
769     // Since the original value is an allocation, it has a pointer type and
770     // therefore no additional wrapping should happen.
771     EXPECT_EQ(&Orig, &Inner);
772 
773     // Trivial copy (=firstprivate).
774     Builder.restoreIP(AllocaIP);
775     Type *VTy = Inner.getType()->getPointerElementType();
776     Value *V = Builder.CreateLoad(VTy, &Inner, Orig.getName() + ".reload");
777     ReplacementValue = Builder.CreateAlloca(VTy, 0, Orig.getName() + ".copy");
778     Builder.restoreIP(CodeGenIP);
779     Builder.CreateStore(V, ReplacementValue);
780     return CodeGenIP;
781   };
782 
783   auto FiniCB = [&](InsertPointTy CodeGenIP) {
784     ++NumFinalizationPoints;
785     // No destructors.
786   };
787 
788   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
789                                     F->getEntryBlock().getFirstInsertionPt());
790   IRBuilder<>::InsertPoint AfterIP =
791       OMPBuilder.createParallel(Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB,
792                                 Builder.CreateIsNotNull(F->arg_begin()),
793                                 nullptr, OMP_PROC_BIND_default, false);
794 
795   EXPECT_EQ(NumBodiesGenerated, 1U);
796   EXPECT_EQ(NumPrivatizedVars, 1U);
797   EXPECT_EQ(NumFinalizationPoints, 1U);
798 
799   Builder.restoreIP(AfterIP);
800   Builder.CreateRetVoid();
801   OMPBuilder.finalize();
802 
803   EXPECT_NE(PrivAI, nullptr);
804   Function *OutlinedFn = PrivAI->getFunction();
805   EXPECT_NE(F, OutlinedFn);
806   EXPECT_FALSE(verifyModule(*M, &errs()));
807 
808   EXPECT_TRUE(OutlinedFn->hasInternalLinkage());
809   EXPECT_EQ(OutlinedFn->arg_size(), 3U);
810 
811   EXPECT_EQ(&OutlinedFn->getEntryBlock(), PrivAI->getParent());
812   ASSERT_EQ(OutlinedFn->getNumUses(), 2U);
813 
814   CallInst *DirectCI = nullptr;
815   CallInst *ForkCI = nullptr;
816   for (User *Usr : OutlinedFn->users()) {
817     if (isa<CallInst>(Usr)) {
818       ASSERT_EQ(DirectCI, nullptr);
819       DirectCI = cast<CallInst>(Usr);
820     } else {
821       ASSERT_TRUE(isa<ConstantExpr>(Usr));
822       ASSERT_EQ(Usr->getNumUses(), 1U);
823       ASSERT_TRUE(isa<CallInst>(Usr->user_back()));
824       ForkCI = cast<CallInst>(Usr->user_back());
825     }
826   }
827 
828   EXPECT_EQ(ForkCI->getCalledFunction()->getName(), "__kmpc_fork_call");
829   EXPECT_EQ(ForkCI->getNumArgOperands(), 4U);
830   EXPECT_TRUE(isa<GlobalVariable>(ForkCI->getArgOperand(0)));
831   EXPECT_EQ(ForkCI->getArgOperand(1),
832             ConstantInt::get(Type::getInt32Ty(Ctx), 1));
833   Value *StoredForkArg = findStoredValue(ForkCI->getArgOperand(3));
834   EXPECT_EQ(StoredForkArg, F->arg_begin());
835 
836   EXPECT_EQ(DirectCI->getCalledFunction(), OutlinedFn);
837   EXPECT_EQ(DirectCI->getNumArgOperands(), 3U);
838   EXPECT_TRUE(isa<AllocaInst>(DirectCI->getArgOperand(0)));
839   EXPECT_TRUE(isa<AllocaInst>(DirectCI->getArgOperand(1)));
840   Value *StoredDirectArg = findStoredValue(DirectCI->getArgOperand(2));
841   EXPECT_EQ(StoredDirectArg, F->arg_begin());
842 }
843 
844 TEST_F(OpenMPIRBuilderTest, ParallelCancelBarrier) {
845   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
846   OpenMPIRBuilder OMPBuilder(*M);
847   OMPBuilder.initialize();
848   F->setName("func");
849   IRBuilder<> Builder(BB);
850 
851   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
852 
853   unsigned NumBodiesGenerated = 0;
854   unsigned NumPrivatizedVars = 0;
855   unsigned NumFinalizationPoints = 0;
856 
857   CallInst *CheckedBarrier = nullptr;
858   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
859                        BasicBlock &ContinuationIP) {
860     ++NumBodiesGenerated;
861 
862     Builder.restoreIP(CodeGenIP);
863 
864     // Create three barriers, two cancel barriers but only one checked.
865     Function *CBFn, *BFn;
866 
867     Builder.restoreIP(
868         OMPBuilder.createBarrier(Builder.saveIP(), OMPD_parallel));
869 
870     CBFn = M->getFunction("__kmpc_cancel_barrier");
871     BFn = M->getFunction("__kmpc_barrier");
872     ASSERT_NE(CBFn, nullptr);
873     ASSERT_EQ(BFn, nullptr);
874     ASSERT_EQ(CBFn->getNumUses(), 1U);
875     ASSERT_TRUE(isa<CallInst>(CBFn->user_back()));
876     ASSERT_EQ(CBFn->user_back()->getNumUses(), 1U);
877     CheckedBarrier = cast<CallInst>(CBFn->user_back());
878 
879     Builder.restoreIP(
880         OMPBuilder.createBarrier(Builder.saveIP(), OMPD_parallel, true));
881     CBFn = M->getFunction("__kmpc_cancel_barrier");
882     BFn = M->getFunction("__kmpc_barrier");
883     ASSERT_NE(CBFn, nullptr);
884     ASSERT_NE(BFn, nullptr);
885     ASSERT_EQ(CBFn->getNumUses(), 1U);
886     ASSERT_EQ(BFn->getNumUses(), 1U);
887     ASSERT_TRUE(isa<CallInst>(BFn->user_back()));
888     ASSERT_EQ(BFn->user_back()->getNumUses(), 0U);
889 
890     Builder.restoreIP(OMPBuilder.createBarrier(Builder.saveIP(), OMPD_parallel,
891                                                false, false));
892     ASSERT_EQ(CBFn->getNumUses(), 2U);
893     ASSERT_EQ(BFn->getNumUses(), 1U);
894     ASSERT_TRUE(CBFn->user_back() != CheckedBarrier);
895     ASSERT_TRUE(isa<CallInst>(CBFn->user_back()));
896     ASSERT_EQ(CBFn->user_back()->getNumUses(), 0U);
897   };
898 
899   auto PrivCB = [&](InsertPointTy, InsertPointTy, Value &V, Value &,
900                     Value *&) -> InsertPointTy {
901     ++NumPrivatizedVars;
902     llvm_unreachable("No privatization callback call expected!");
903   };
904 
905   FunctionType *FakeDestructorTy =
906       FunctionType::get(Type::getVoidTy(Ctx), {Type::getInt32Ty(Ctx)},
907                         /*isVarArg=*/false);
908   auto *FakeDestructor = Function::Create(
909       FakeDestructorTy, Function::ExternalLinkage, "fakeDestructor", M.get());
910 
911   auto FiniCB = [&](InsertPointTy IP) {
912     ++NumFinalizationPoints;
913     Builder.restoreIP(IP);
914     Builder.CreateCall(FakeDestructor,
915                        {Builder.getInt32(NumFinalizationPoints)});
916   };
917 
918   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
919                                     F->getEntryBlock().getFirstInsertionPt());
920   IRBuilder<>::InsertPoint AfterIP =
921       OMPBuilder.createParallel(Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB,
922                                 Builder.CreateIsNotNull(F->arg_begin()),
923                                 nullptr, OMP_PROC_BIND_default, true);
924 
925   EXPECT_EQ(NumBodiesGenerated, 1U);
926   EXPECT_EQ(NumPrivatizedVars, 0U);
927   EXPECT_EQ(NumFinalizationPoints, 2U);
928   EXPECT_EQ(FakeDestructor->getNumUses(), 2U);
929 
930   Builder.restoreIP(AfterIP);
931   Builder.CreateRetVoid();
932   OMPBuilder.finalize();
933 
934   EXPECT_FALSE(verifyModule(*M, &errs()));
935 
936   BasicBlock *ExitBB = nullptr;
937   for (const User *Usr : FakeDestructor->users()) {
938     const CallInst *CI = dyn_cast<CallInst>(Usr);
939     ASSERT_EQ(CI->getCalledFunction(), FakeDestructor);
940     ASSERT_TRUE(isa<BranchInst>(CI->getNextNode()));
941     ASSERT_EQ(CI->getNextNode()->getNumSuccessors(), 1U);
942     if (ExitBB)
943       ASSERT_EQ(CI->getNextNode()->getSuccessor(0), ExitBB);
944     else
945       ExitBB = CI->getNextNode()->getSuccessor(0);
946     ASSERT_EQ(ExitBB->size(), 1U);
947     if (!isa<ReturnInst>(ExitBB->front())) {
948       ASSERT_TRUE(isa<BranchInst>(ExitBB->front()));
949       ASSERT_EQ(cast<BranchInst>(ExitBB->front()).getNumSuccessors(), 1U);
950       ASSERT_TRUE(isa<ReturnInst>(
951           cast<BranchInst>(ExitBB->front()).getSuccessor(0)->front()));
952     }
953   }
954 }
955 
956 TEST_F(OpenMPIRBuilderTest, ParallelForwardAsPointers) {
957   OpenMPIRBuilder OMPBuilder(*M);
958   OMPBuilder.initialize();
959   F->setName("func");
960   IRBuilder<> Builder(BB);
961   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
962   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
963 
964   Type *I32Ty = Type::getInt32Ty(M->getContext());
965   Type *I32PtrTy = Type::getInt32PtrTy(M->getContext());
966   Type *StructTy = StructType::get(I32Ty, I32PtrTy);
967   Type *StructPtrTy = StructTy->getPointerTo();
968   Type *VoidTy = Type::getVoidTy(M->getContext());
969   FunctionCallee RetI32Func = M->getOrInsertFunction("ret_i32", I32Ty);
970   FunctionCallee TakeI32Func =
971       M->getOrInsertFunction("take_i32", VoidTy, I32Ty);
972   FunctionCallee RetI32PtrFunc = M->getOrInsertFunction("ret_i32ptr", I32PtrTy);
973   FunctionCallee TakeI32PtrFunc =
974       M->getOrInsertFunction("take_i32ptr", VoidTy, I32PtrTy);
975   FunctionCallee RetStructFunc = M->getOrInsertFunction("ret_struct", StructTy);
976   FunctionCallee TakeStructFunc =
977       M->getOrInsertFunction("take_struct", VoidTy, StructTy);
978   FunctionCallee RetStructPtrFunc =
979       M->getOrInsertFunction("ret_structptr", StructPtrTy);
980   FunctionCallee TakeStructPtrFunc =
981       M->getOrInsertFunction("take_structPtr", VoidTy, StructPtrTy);
982   Value *I32Val = Builder.CreateCall(RetI32Func);
983   Value *I32PtrVal = Builder.CreateCall(RetI32PtrFunc);
984   Value *StructVal = Builder.CreateCall(RetStructFunc);
985   Value *StructPtrVal = Builder.CreateCall(RetStructPtrFunc);
986 
987   Instruction *Internal;
988   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
989                        BasicBlock &ContinuationBB) {
990     IRBuilder<>::InsertPointGuard Guard(Builder);
991     Builder.restoreIP(CodeGenIP);
992     Internal = Builder.CreateCall(TakeI32Func, I32Val);
993     Builder.CreateCall(TakeI32PtrFunc, I32PtrVal);
994     Builder.CreateCall(TakeStructFunc, StructVal);
995     Builder.CreateCall(TakeStructPtrFunc, StructPtrVal);
996   };
997   auto PrivCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &,
998                     Value &Inner, Value *&ReplacementValue) {
999     ReplacementValue = &Inner;
1000     return CodeGenIP;
1001   };
1002   auto FiniCB = [](InsertPointTy) {};
1003 
1004   IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
1005                                     F->getEntryBlock().getFirstInsertionPt());
1006   IRBuilder<>::InsertPoint AfterIP =
1007       OMPBuilder.createParallel(Loc, AllocaIP, BodyGenCB, PrivCB, FiniCB,
1008                                 nullptr, nullptr, OMP_PROC_BIND_default, false);
1009   Builder.restoreIP(AfterIP);
1010   Builder.CreateRetVoid();
1011 
1012   OMPBuilder.finalize();
1013 
1014   EXPECT_FALSE(verifyModule(*M, &errs()));
1015   Function *OutlinedFn = Internal->getFunction();
1016 
1017   Type *Arg2Type = OutlinedFn->getArg(2)->getType();
1018   EXPECT_TRUE(Arg2Type->isPointerTy());
1019   EXPECT_EQ(Arg2Type->getPointerElementType(), I32Ty);
1020 
1021   // Arguments that need to be passed through pointers and reloaded will get
1022   // used earlier in the functions and therefore will appear first in the
1023   // argument list after outlining.
1024   Type *Arg3Type = OutlinedFn->getArg(3)->getType();
1025   EXPECT_TRUE(Arg3Type->isPointerTy());
1026   EXPECT_EQ(Arg3Type->getPointerElementType(), StructTy);
1027 
1028   Type *Arg4Type = OutlinedFn->getArg(4)->getType();
1029   EXPECT_EQ(Arg4Type, I32PtrTy);
1030 
1031   Type *Arg5Type = OutlinedFn->getArg(5)->getType();
1032   EXPECT_EQ(Arg5Type, StructPtrTy);
1033 }
1034 
1035 TEST_F(OpenMPIRBuilderTest, CanonicalLoopSimple) {
1036   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1037   OpenMPIRBuilder OMPBuilder(*M);
1038   OMPBuilder.initialize();
1039   IRBuilder<> Builder(BB);
1040   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1041   Value *TripCount = F->getArg(0);
1042 
1043   unsigned NumBodiesGenerated = 0;
1044   auto LoopBodyGenCB = [&](InsertPointTy CodeGenIP, llvm::Value *LC) {
1045     NumBodiesGenerated += 1;
1046 
1047     Builder.restoreIP(CodeGenIP);
1048 
1049     Value *Cmp = Builder.CreateICmpEQ(LC, TripCount);
1050     Instruction *ThenTerm, *ElseTerm;
1051     SplitBlockAndInsertIfThenElse(Cmp, CodeGenIP.getBlock()->getTerminator(),
1052                                   &ThenTerm, &ElseTerm);
1053   };
1054 
1055   CanonicalLoopInfo *Loop =
1056       OMPBuilder.createCanonicalLoop(Loc, LoopBodyGenCB, TripCount);
1057 
1058   Builder.restoreIP(Loop->getAfterIP());
1059   ReturnInst *RetInst = Builder.CreateRetVoid();
1060   OMPBuilder.finalize();
1061 
1062   Loop->assertOK();
1063   EXPECT_FALSE(verifyModule(*M, &errs()));
1064 
1065   EXPECT_EQ(NumBodiesGenerated, 1U);
1066 
1067   // Verify control flow structure (in addition to Loop->assertOK()).
1068   EXPECT_EQ(Loop->getPreheader()->getSinglePredecessor(), &F->getEntryBlock());
1069   EXPECT_EQ(Loop->getAfter(), Builder.GetInsertBlock());
1070 
1071   Instruction *IndVar = Loop->getIndVar();
1072   EXPECT_TRUE(isa<PHINode>(IndVar));
1073   EXPECT_EQ(IndVar->getType(), TripCount->getType());
1074   EXPECT_EQ(IndVar->getParent(), Loop->getHeader());
1075 
1076   EXPECT_EQ(Loop->getTripCount(), TripCount);
1077 
1078   BasicBlock *Body = Loop->getBody();
1079   Instruction *CmpInst = &Body->getInstList().front();
1080   EXPECT_TRUE(isa<ICmpInst>(CmpInst));
1081   EXPECT_EQ(CmpInst->getOperand(0), IndVar);
1082 
1083   BasicBlock *LatchPred = Loop->getLatch()->getSinglePredecessor();
1084   EXPECT_TRUE(llvm::all_of(successors(Body), [=](BasicBlock *SuccBB) {
1085     return SuccBB->getSingleSuccessor() == LatchPred;
1086   }));
1087 
1088   EXPECT_EQ(&Loop->getAfter()->front(), RetInst);
1089 }
1090 
1091 TEST_F(OpenMPIRBuilderTest, CanonicalLoopBounds) {
1092   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1093   OpenMPIRBuilder OMPBuilder(*M);
1094   OMPBuilder.initialize();
1095   IRBuilder<> Builder(BB);
1096 
1097   // Check the trip count is computed correctly. We generate the canonical loop
1098   // but rely on the IRBuilder's constant folder to compute the final result
1099   // since all inputs are constant. To verify overflow situations, limit the
1100   // trip count / loop counter widths to 16 bits.
1101   auto EvalTripCount = [&](int64_t Start, int64_t Stop, int64_t Step,
1102                            bool IsSigned, bool InclusiveStop) -> int64_t {
1103     OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1104     Type *LCTy = Type::getInt16Ty(Ctx);
1105     Value *StartVal = ConstantInt::get(LCTy, Start);
1106     Value *StopVal = ConstantInt::get(LCTy, Stop);
1107     Value *StepVal = ConstantInt::get(LCTy, Step);
1108     auto LoopBodyGenCB = [&](InsertPointTy CodeGenIP, llvm::Value *LC) {};
1109     CanonicalLoopInfo *Loop =
1110         OMPBuilder.createCanonicalLoop(Loc, LoopBodyGenCB, StartVal, StopVal,
1111                                        StepVal, IsSigned, InclusiveStop);
1112     Loop->assertOK();
1113     Builder.restoreIP(Loop->getAfterIP());
1114     Value *TripCount = Loop->getTripCount();
1115     return cast<ConstantInt>(TripCount)->getValue().getZExtValue();
1116   };
1117 
1118   EXPECT_EQ(EvalTripCount(0, 0, 1, false, false), 0);
1119   EXPECT_EQ(EvalTripCount(0, 1, 2, false, false), 1);
1120   EXPECT_EQ(EvalTripCount(0, 42, 1, false, false), 42);
1121   EXPECT_EQ(EvalTripCount(0, 42, 2, false, false), 21);
1122   EXPECT_EQ(EvalTripCount(21, 42, 1, false, false), 21);
1123   EXPECT_EQ(EvalTripCount(0, 5, 5, false, false), 1);
1124   EXPECT_EQ(EvalTripCount(0, 9, 5, false, false), 2);
1125   EXPECT_EQ(EvalTripCount(0, 11, 5, false, false), 3);
1126   EXPECT_EQ(EvalTripCount(0, 0xFFFF, 1, false, false), 0xFFFF);
1127   EXPECT_EQ(EvalTripCount(0xFFFF, 0, 1, false, false), 0);
1128   EXPECT_EQ(EvalTripCount(0xFFFE, 0xFFFF, 1, false, false), 1);
1129   EXPECT_EQ(EvalTripCount(0, 0xFFFF, 0x100, false, false), 0x100);
1130   EXPECT_EQ(EvalTripCount(0, 0xFFFF, 0xFFFF, false, false), 1);
1131 
1132   EXPECT_EQ(EvalTripCount(0, 6, 5, false, false), 2);
1133   EXPECT_EQ(EvalTripCount(0, 0xFFFF, 0xFFFE, false, false), 2);
1134   EXPECT_EQ(EvalTripCount(0, 0, 1, false, true), 1);
1135   EXPECT_EQ(EvalTripCount(0, 0, 0xFFFF, false, true), 1);
1136   EXPECT_EQ(EvalTripCount(0, 0xFFFE, 1, false, true), 0xFFFF);
1137   EXPECT_EQ(EvalTripCount(0, 0xFFFE, 2, false, true), 0x8000);
1138 
1139   EXPECT_EQ(EvalTripCount(0, 0, -1, true, false), 0);
1140   EXPECT_EQ(EvalTripCount(0, 1, -1, true, true), 0);
1141   EXPECT_EQ(EvalTripCount(20, 5, -5, true, false), 3);
1142   EXPECT_EQ(EvalTripCount(20, 5, -5, true, true), 4);
1143   EXPECT_EQ(EvalTripCount(-4, -2, 2, true, false), 1);
1144   EXPECT_EQ(EvalTripCount(-4, -3, 2, true, false), 1);
1145   EXPECT_EQ(EvalTripCount(-4, -2, 2, true, true), 2);
1146 
1147   EXPECT_EQ(EvalTripCount(INT16_MIN, 0, 1, true, false), 0x8000);
1148   EXPECT_EQ(EvalTripCount(INT16_MIN, 0, 1, true, true), 0x8001);
1149   EXPECT_EQ(EvalTripCount(INT16_MIN, 0x7FFF, 1, true, false), 0xFFFF);
1150   EXPECT_EQ(EvalTripCount(INT16_MIN + 1, 0x7FFF, 1, true, true), 0xFFFF);
1151   EXPECT_EQ(EvalTripCount(INT16_MIN, 0, 0x7FFF, true, false), 2);
1152   EXPECT_EQ(EvalTripCount(0x7FFF, 0, -1, true, false), 0x7FFF);
1153   EXPECT_EQ(EvalTripCount(0, INT16_MIN, -1, true, false), 0x8000);
1154   EXPECT_EQ(EvalTripCount(0, INT16_MIN, -16, true, false), 0x800);
1155   EXPECT_EQ(EvalTripCount(0x7FFF, INT16_MIN, -1, true, false), 0xFFFF);
1156   EXPECT_EQ(EvalTripCount(0x7FFF, 1, INT16_MIN, true, false), 1);
1157   EXPECT_EQ(EvalTripCount(0x7FFF, -1, INT16_MIN, true, true), 2);
1158 
1159   // Finalize the function and verify it.
1160   Builder.CreateRetVoid();
1161   OMPBuilder.finalize();
1162   EXPECT_FALSE(verifyModule(*M, &errs()));
1163 }
1164 
1165 TEST_F(OpenMPIRBuilderTest, CollapseNestedLoops) {
1166   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1167   OpenMPIRBuilder OMPBuilder(*M);
1168   OMPBuilder.initialize();
1169   F->setName("func");
1170 
1171   IRBuilder<> Builder(BB);
1172 
1173   Type *LCTy = F->getArg(0)->getType();
1174   Constant *One = ConstantInt::get(LCTy, 1);
1175   Constant *Two = ConstantInt::get(LCTy, 2);
1176   Value *OuterTripCount =
1177       Builder.CreateAdd(F->getArg(0), Two, "tripcount.outer");
1178   Value *InnerTripCount =
1179       Builder.CreateAdd(F->getArg(0), One, "tripcount.inner");
1180 
1181   // Fix an insertion point for ComputeIP.
1182   BasicBlock *LoopNextEnter =
1183       BasicBlock::Create(M->getContext(), "loopnest.enter", F,
1184                          Builder.GetInsertBlock()->getNextNode());
1185   BranchInst *EnterBr = Builder.CreateBr(LoopNextEnter);
1186   InsertPointTy ComputeIP{EnterBr->getParent(), EnterBr->getIterator()};
1187 
1188   Builder.SetInsertPoint(LoopNextEnter);
1189   OpenMPIRBuilder::LocationDescription OuterLoc(Builder.saveIP(), DL);
1190 
1191   CanonicalLoopInfo *InnerLoop = nullptr;
1192   CallInst *InbetweenLead = nullptr;
1193   CallInst *InbetweenTrail = nullptr;
1194   CallInst *Call = nullptr;
1195   auto OuterLoopBodyGenCB = [&](InsertPointTy OuterCodeGenIP, Value *OuterLC) {
1196     Builder.restoreIP(OuterCodeGenIP);
1197     InbetweenLead =
1198         createPrintfCall(Builder, "In-between lead i=%d\\n", {OuterLC});
1199 
1200     auto InnerLoopBodyGenCB = [&](InsertPointTy InnerCodeGenIP,
1201                                   Value *InnerLC) {
1202       Builder.restoreIP(InnerCodeGenIP);
1203       Call = createPrintfCall(Builder, "body i=%d j=%d\\n", {OuterLC, InnerLC});
1204     };
1205     InnerLoop = OMPBuilder.createCanonicalLoop(
1206         Builder.saveIP(), InnerLoopBodyGenCB, InnerTripCount, "inner");
1207 
1208     Builder.restoreIP(InnerLoop->getAfterIP());
1209     InbetweenTrail =
1210         createPrintfCall(Builder, "In-between trail i=%d\\n", {OuterLC});
1211   };
1212   CanonicalLoopInfo *OuterLoop = OMPBuilder.createCanonicalLoop(
1213       OuterLoc, OuterLoopBodyGenCB, OuterTripCount, "outer");
1214 
1215   // Finish the function.
1216   Builder.restoreIP(OuterLoop->getAfterIP());
1217   Builder.CreateRetVoid();
1218 
1219   CanonicalLoopInfo *Collapsed =
1220       OMPBuilder.collapseLoops(DL, {OuterLoop, InnerLoop}, ComputeIP);
1221 
1222   OMPBuilder.finalize();
1223   EXPECT_FALSE(verifyModule(*M, &errs()));
1224 
1225   // Verify control flow and BB order.
1226   BasicBlock *RefOrder[] = {
1227       Collapsed->getPreheader(),   Collapsed->getHeader(),
1228       Collapsed->getCond(),        Collapsed->getBody(),
1229       InbetweenLead->getParent(),  Call->getParent(),
1230       InbetweenTrail->getParent(), Collapsed->getLatch(),
1231       Collapsed->getExit(),        Collapsed->getAfter(),
1232   };
1233   EXPECT_TRUE(verifyDFSOrder(F, RefOrder));
1234   EXPECT_TRUE(verifyListOrder(F, RefOrder));
1235 
1236   // Verify the total trip count.
1237   auto *TripCount = cast<MulOperator>(Collapsed->getTripCount());
1238   EXPECT_EQ(TripCount->getOperand(0), OuterTripCount);
1239   EXPECT_EQ(TripCount->getOperand(1), InnerTripCount);
1240 
1241   // Verify the changed indvar.
1242   auto *OuterIV = cast<BinaryOperator>(Call->getOperand(1));
1243   EXPECT_EQ(OuterIV->getOpcode(), Instruction::UDiv);
1244   EXPECT_EQ(OuterIV->getParent(), Collapsed->getBody());
1245   EXPECT_EQ(OuterIV->getOperand(1), InnerTripCount);
1246   EXPECT_EQ(OuterIV->getOperand(0), Collapsed->getIndVar());
1247 
1248   auto *InnerIV = cast<BinaryOperator>(Call->getOperand(2));
1249   EXPECT_EQ(InnerIV->getOpcode(), Instruction::URem);
1250   EXPECT_EQ(InnerIV->getParent(), Collapsed->getBody());
1251   EXPECT_EQ(InnerIV->getOperand(0), Collapsed->getIndVar());
1252   EXPECT_EQ(InnerIV->getOperand(1), InnerTripCount);
1253 
1254   EXPECT_EQ(InbetweenLead->getOperand(1), OuterIV);
1255   EXPECT_EQ(InbetweenTrail->getOperand(1), OuterIV);
1256 }
1257 
1258 TEST_F(OpenMPIRBuilderTest, TileSingleLoop) {
1259   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1260   OpenMPIRBuilder OMPBuilder(*M);
1261   OMPBuilder.initialize();
1262   F->setName("func");
1263 
1264   IRBuilder<> Builder(BB);
1265   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1266   Value *TripCount = F->getArg(0);
1267 
1268   BasicBlock *BodyCode = nullptr;
1269   Instruction *Call = nullptr;
1270   auto LoopBodyGenCB = [&](InsertPointTy CodeGenIP, llvm::Value *LC) {
1271     Builder.restoreIP(CodeGenIP);
1272     BodyCode = Builder.GetInsertBlock();
1273 
1274     // Add something that consumes the induction variable to the body.
1275     Call = createPrintfCall(Builder, "%d\\n", {LC});
1276   };
1277   CanonicalLoopInfo *Loop =
1278       OMPBuilder.createCanonicalLoop(Loc, LoopBodyGenCB, TripCount);
1279 
1280   // Finalize the function.
1281   Builder.restoreIP(Loop->getAfterIP());
1282   Builder.CreateRetVoid();
1283 
1284   Instruction *OrigIndVar = Loop->getIndVar();
1285   EXPECT_EQ(Call->getOperand(1), OrigIndVar);
1286 
1287   // Tile the loop.
1288   Constant *TileSize = ConstantInt::get(Loop->getIndVarType(), APInt(32, 7));
1289   std::vector<CanonicalLoopInfo *> GenLoops =
1290       OMPBuilder.tileLoops(DL, {Loop}, {TileSize});
1291 
1292   OMPBuilder.finalize();
1293   EXPECT_FALSE(verifyModule(*M, &errs()));
1294 
1295   EXPECT_EQ(GenLoops.size(), 2u);
1296   CanonicalLoopInfo *Floor = GenLoops[0];
1297   CanonicalLoopInfo *Tile = GenLoops[1];
1298 
1299   BasicBlock *RefOrder[] = {
1300       Floor->getPreheader(), Floor->getHeader(),   Floor->getCond(),
1301       Floor->getBody(),      Tile->getPreheader(), Tile->getHeader(),
1302       Tile->getCond(),       Tile->getBody(),      BodyCode,
1303       Tile->getLatch(),      Tile->getExit(),      Tile->getAfter(),
1304       Floor->getLatch(),     Floor->getExit(),     Floor->getAfter(),
1305   };
1306   EXPECT_TRUE(verifyDFSOrder(F, RefOrder));
1307   EXPECT_TRUE(verifyListOrder(F, RefOrder));
1308 
1309   // Check the induction variable.
1310   EXPECT_EQ(Call->getParent(), BodyCode);
1311   auto *Shift = cast<AddOperator>(Call->getOperand(1));
1312   EXPECT_EQ(cast<Instruction>(Shift)->getParent(), Tile->getBody());
1313   EXPECT_EQ(Shift->getOperand(1), Tile->getIndVar());
1314   auto *Scale = cast<MulOperator>(Shift->getOperand(0));
1315   EXPECT_EQ(cast<Instruction>(Scale)->getParent(), Tile->getBody());
1316   EXPECT_EQ(Scale->getOperand(0), TileSize);
1317   EXPECT_EQ(Scale->getOperand(1), Floor->getIndVar());
1318 }
1319 
1320 TEST_F(OpenMPIRBuilderTest, TileNestedLoops) {
1321   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1322   OpenMPIRBuilder OMPBuilder(*M);
1323   OMPBuilder.initialize();
1324   F->setName("func");
1325 
1326   IRBuilder<> Builder(BB);
1327   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1328   Value *TripCount = F->getArg(0);
1329   Type *LCTy = TripCount->getType();
1330 
1331   BasicBlock *BodyCode = nullptr;
1332   CanonicalLoopInfo *InnerLoop = nullptr;
1333   auto OuterLoopBodyGenCB = [&](InsertPointTy OuterCodeGenIP,
1334                                 llvm::Value *OuterLC) {
1335     auto InnerLoopBodyGenCB = [&](InsertPointTy InnerCodeGenIP,
1336                                   llvm::Value *InnerLC) {
1337       Builder.restoreIP(InnerCodeGenIP);
1338       BodyCode = Builder.GetInsertBlock();
1339 
1340       // Add something that consumes the induction variables to the body.
1341       createPrintfCall(Builder, "i=%d j=%d\\n", {OuterLC, InnerLC});
1342     };
1343     InnerLoop = OMPBuilder.createCanonicalLoop(
1344         OuterCodeGenIP, InnerLoopBodyGenCB, TripCount, "inner");
1345   };
1346   CanonicalLoopInfo *OuterLoop = OMPBuilder.createCanonicalLoop(
1347       Loc, OuterLoopBodyGenCB, TripCount, "outer");
1348 
1349   // Finalize the function.
1350   Builder.restoreIP(OuterLoop->getAfterIP());
1351   Builder.CreateRetVoid();
1352 
1353   // Tile to loop nest.
1354   Constant *OuterTileSize = ConstantInt::get(LCTy, APInt(32, 11));
1355   Constant *InnerTileSize = ConstantInt::get(LCTy, APInt(32, 7));
1356   std::vector<CanonicalLoopInfo *> GenLoops = OMPBuilder.tileLoops(
1357       DL, {OuterLoop, InnerLoop}, {OuterTileSize, InnerTileSize});
1358 
1359   OMPBuilder.finalize();
1360   EXPECT_FALSE(verifyModule(*M, &errs()));
1361 
1362   EXPECT_EQ(GenLoops.size(), 4u);
1363   CanonicalLoopInfo *Floor1 = GenLoops[0];
1364   CanonicalLoopInfo *Floor2 = GenLoops[1];
1365   CanonicalLoopInfo *Tile1 = GenLoops[2];
1366   CanonicalLoopInfo *Tile2 = GenLoops[3];
1367 
1368   BasicBlock *RefOrder[] = {
1369       Floor1->getPreheader(),
1370       Floor1->getHeader(),
1371       Floor1->getCond(),
1372       Floor1->getBody(),
1373       Floor2->getPreheader(),
1374       Floor2->getHeader(),
1375       Floor2->getCond(),
1376       Floor2->getBody(),
1377       Tile1->getPreheader(),
1378       Tile1->getHeader(),
1379       Tile1->getCond(),
1380       Tile1->getBody(),
1381       Tile2->getPreheader(),
1382       Tile2->getHeader(),
1383       Tile2->getCond(),
1384       Tile2->getBody(),
1385       BodyCode,
1386       Tile2->getLatch(),
1387       Tile2->getExit(),
1388       Tile2->getAfter(),
1389       Tile1->getLatch(),
1390       Tile1->getExit(),
1391       Tile1->getAfter(),
1392       Floor2->getLatch(),
1393       Floor2->getExit(),
1394       Floor2->getAfter(),
1395       Floor1->getLatch(),
1396       Floor1->getExit(),
1397       Floor1->getAfter(),
1398   };
1399   EXPECT_TRUE(verifyDFSOrder(F, RefOrder));
1400   EXPECT_TRUE(verifyListOrder(F, RefOrder));
1401 }
1402 
1403 TEST_F(OpenMPIRBuilderTest, TileNestedLoopsWithBounds) {
1404   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1405   OpenMPIRBuilder OMPBuilder(*M);
1406   OMPBuilder.initialize();
1407   F->setName("func");
1408 
1409   IRBuilder<> Builder(BB);
1410   Value *TripCount = F->getArg(0);
1411   Type *LCTy = TripCount->getType();
1412 
1413   Value *OuterStartVal = ConstantInt::get(LCTy, 2);
1414   Value *OuterStopVal = TripCount;
1415   Value *OuterStep = ConstantInt::get(LCTy, 5);
1416   Value *InnerStartVal = ConstantInt::get(LCTy, 13);
1417   Value *InnerStopVal = TripCount;
1418   Value *InnerStep = ConstantInt::get(LCTy, 3);
1419 
1420   // Fix an insertion point for ComputeIP.
1421   BasicBlock *LoopNextEnter =
1422       BasicBlock::Create(M->getContext(), "loopnest.enter", F,
1423                          Builder.GetInsertBlock()->getNextNode());
1424   BranchInst *EnterBr = Builder.CreateBr(LoopNextEnter);
1425   InsertPointTy ComputeIP{EnterBr->getParent(), EnterBr->getIterator()};
1426 
1427   InsertPointTy LoopIP{LoopNextEnter, LoopNextEnter->begin()};
1428   OpenMPIRBuilder::LocationDescription Loc({LoopIP, DL});
1429 
1430   BasicBlock *BodyCode = nullptr;
1431   CanonicalLoopInfo *InnerLoop = nullptr;
1432   CallInst *Call = nullptr;
1433   auto OuterLoopBodyGenCB = [&](InsertPointTy OuterCodeGenIP,
1434                                 llvm::Value *OuterLC) {
1435     auto InnerLoopBodyGenCB = [&](InsertPointTy InnerCodeGenIP,
1436                                   llvm::Value *InnerLC) {
1437       Builder.restoreIP(InnerCodeGenIP);
1438       BodyCode = Builder.GetInsertBlock();
1439 
1440       // Add something that consumes the induction variable to the body.
1441       Call = createPrintfCall(Builder, "i=%d j=%d\\n", {OuterLC, InnerLC});
1442     };
1443     InnerLoop = OMPBuilder.createCanonicalLoop(
1444         OuterCodeGenIP, InnerLoopBodyGenCB, InnerStartVal, InnerStopVal,
1445         InnerStep, false, false, ComputeIP, "inner");
1446   };
1447   CanonicalLoopInfo *OuterLoop = OMPBuilder.createCanonicalLoop(
1448       Loc, OuterLoopBodyGenCB, OuterStartVal, OuterStopVal, OuterStep, false,
1449       false, ComputeIP, "outer");
1450 
1451   // Finalize the function
1452   Builder.restoreIP(OuterLoop->getAfterIP());
1453   Builder.CreateRetVoid();
1454 
1455   // Tile the loop nest.
1456   Constant *TileSize0 = ConstantInt::get(LCTy, APInt(32, 11));
1457   Constant *TileSize1 = ConstantInt::get(LCTy, APInt(32, 7));
1458   std::vector<CanonicalLoopInfo *> GenLoops =
1459       OMPBuilder.tileLoops(DL, {OuterLoop, InnerLoop}, {TileSize0, TileSize1});
1460 
1461   OMPBuilder.finalize();
1462   EXPECT_FALSE(verifyModule(*M, &errs()));
1463 
1464   EXPECT_EQ(GenLoops.size(), 4u);
1465   CanonicalLoopInfo *Floor0 = GenLoops[0];
1466   CanonicalLoopInfo *Floor1 = GenLoops[1];
1467   CanonicalLoopInfo *Tile0 = GenLoops[2];
1468   CanonicalLoopInfo *Tile1 = GenLoops[3];
1469 
1470   BasicBlock *RefOrder[] = {
1471       Floor0->getPreheader(),
1472       Floor0->getHeader(),
1473       Floor0->getCond(),
1474       Floor0->getBody(),
1475       Floor1->getPreheader(),
1476       Floor1->getHeader(),
1477       Floor1->getCond(),
1478       Floor1->getBody(),
1479       Tile0->getPreheader(),
1480       Tile0->getHeader(),
1481       Tile0->getCond(),
1482       Tile0->getBody(),
1483       Tile1->getPreheader(),
1484       Tile1->getHeader(),
1485       Tile1->getCond(),
1486       Tile1->getBody(),
1487       BodyCode,
1488       Tile1->getLatch(),
1489       Tile1->getExit(),
1490       Tile1->getAfter(),
1491       Tile0->getLatch(),
1492       Tile0->getExit(),
1493       Tile0->getAfter(),
1494       Floor1->getLatch(),
1495       Floor1->getExit(),
1496       Floor1->getAfter(),
1497       Floor0->getLatch(),
1498       Floor0->getExit(),
1499       Floor0->getAfter(),
1500   };
1501   EXPECT_TRUE(verifyDFSOrder(F, RefOrder));
1502   EXPECT_TRUE(verifyListOrder(F, RefOrder));
1503 
1504   EXPECT_EQ(Call->getParent(), BodyCode);
1505 
1506   auto *RangeShift0 = cast<AddOperator>(Call->getOperand(1));
1507   EXPECT_EQ(RangeShift0->getOperand(1), OuterStartVal);
1508   auto *RangeScale0 = cast<MulOperator>(RangeShift0->getOperand(0));
1509   EXPECT_EQ(RangeScale0->getOperand(1), OuterStep);
1510   auto *TileShift0 = cast<AddOperator>(RangeScale0->getOperand(0));
1511   EXPECT_EQ(cast<Instruction>(TileShift0)->getParent(), Tile1->getBody());
1512   EXPECT_EQ(TileShift0->getOperand(1), Tile0->getIndVar());
1513   auto *TileScale0 = cast<MulOperator>(TileShift0->getOperand(0));
1514   EXPECT_EQ(cast<Instruction>(TileScale0)->getParent(), Tile1->getBody());
1515   EXPECT_EQ(TileScale0->getOperand(0), TileSize0);
1516   EXPECT_EQ(TileScale0->getOperand(1), Floor0->getIndVar());
1517 
1518   auto *RangeShift1 = cast<AddOperator>(Call->getOperand(2));
1519   EXPECT_EQ(cast<Instruction>(RangeShift1)->getParent(), BodyCode);
1520   EXPECT_EQ(RangeShift1->getOperand(1), InnerStartVal);
1521   auto *RangeScale1 = cast<MulOperator>(RangeShift1->getOperand(0));
1522   EXPECT_EQ(cast<Instruction>(RangeScale1)->getParent(), BodyCode);
1523   EXPECT_EQ(RangeScale1->getOperand(1), InnerStep);
1524   auto *TileShift1 = cast<AddOperator>(RangeScale1->getOperand(0));
1525   EXPECT_EQ(cast<Instruction>(TileShift1)->getParent(), Tile1->getBody());
1526   EXPECT_EQ(TileShift1->getOperand(1), Tile1->getIndVar());
1527   auto *TileScale1 = cast<MulOperator>(TileShift1->getOperand(0));
1528   EXPECT_EQ(cast<Instruction>(TileScale1)->getParent(), Tile1->getBody());
1529   EXPECT_EQ(TileScale1->getOperand(0), TileSize1);
1530   EXPECT_EQ(TileScale1->getOperand(1), Floor1->getIndVar());
1531 }
1532 
1533 TEST_F(OpenMPIRBuilderTest, TileSingleLoopCounts) {
1534   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1535   OpenMPIRBuilder OMPBuilder(*M);
1536   OMPBuilder.initialize();
1537   IRBuilder<> Builder(BB);
1538 
1539   // Create a loop, tile it, and extract its trip count. All input values are
1540   // constant and IRBuilder evaluates all-constant arithmetic inplace, such that
1541   // the floor trip count itself will be a ConstantInt. Unfortunately we cannot
1542   // do the same for the tile loop.
1543   auto GetFloorCount = [&](int64_t Start, int64_t Stop, int64_t Step,
1544                            bool IsSigned, bool InclusiveStop,
1545                            int64_t TileSize) -> uint64_t {
1546     OpenMPIRBuilder::LocationDescription Loc(Builder.saveIP(), DL);
1547     Type *LCTy = Type::getInt16Ty(Ctx);
1548     Value *StartVal = ConstantInt::get(LCTy, Start);
1549     Value *StopVal = ConstantInt::get(LCTy, Stop);
1550     Value *StepVal = ConstantInt::get(LCTy, Step);
1551 
1552     // Generate a loop.
1553     auto LoopBodyGenCB = [&](InsertPointTy CodeGenIP, llvm::Value *LC) {};
1554     CanonicalLoopInfo *Loop =
1555         OMPBuilder.createCanonicalLoop(Loc, LoopBodyGenCB, StartVal, StopVal,
1556                                        StepVal, IsSigned, InclusiveStop);
1557 
1558     // Tile the loop.
1559     Value *TileSizeVal = ConstantInt::get(LCTy, TileSize);
1560     std::vector<CanonicalLoopInfo *> GenLoops =
1561         OMPBuilder.tileLoops(Loc.DL, {Loop}, {TileSizeVal});
1562 
1563     // Set the insertion pointer to after loop, where the next loop will be
1564     // emitted.
1565     Builder.restoreIP(Loop->getAfterIP());
1566 
1567     // Extract the trip count.
1568     CanonicalLoopInfo *FloorLoop = GenLoops[0];
1569     Value *FloorTripCount = FloorLoop->getTripCount();
1570     return cast<ConstantInt>(FloorTripCount)->getValue().getZExtValue();
1571   };
1572 
1573   // Empty iteration domain.
1574   EXPECT_EQ(GetFloorCount(0, 0, 1, false, false, 7), 0u);
1575   EXPECT_EQ(GetFloorCount(0, -1, 1, false, true, 7), 0u);
1576   EXPECT_EQ(GetFloorCount(-1, -1, -1, true, false, 7), 0u);
1577   EXPECT_EQ(GetFloorCount(-1, 0, -1, true, true, 7), 0u);
1578   EXPECT_EQ(GetFloorCount(-1, -1, 3, true, false, 7), 0u);
1579 
1580   // Only complete tiles.
1581   EXPECT_EQ(GetFloorCount(0, 14, 1, false, false, 7), 2u);
1582   EXPECT_EQ(GetFloorCount(0, 14, 1, false, false, 7), 2u);
1583   EXPECT_EQ(GetFloorCount(1, 15, 1, false, false, 7), 2u);
1584   EXPECT_EQ(GetFloorCount(0, -14, -1, true, false, 7), 2u);
1585   EXPECT_EQ(GetFloorCount(-1, -14, -1, true, true, 7), 2u);
1586   EXPECT_EQ(GetFloorCount(0, 3 * 7 * 2, 3, false, false, 7), 2u);
1587 
1588   // Only a partial tile.
1589   EXPECT_EQ(GetFloorCount(0, 1, 1, false, false, 7), 1u);
1590   EXPECT_EQ(GetFloorCount(0, 6, 1, false, false, 7), 1u);
1591   EXPECT_EQ(GetFloorCount(-1, 1, 3, true, false, 7), 1u);
1592   EXPECT_EQ(GetFloorCount(-1, -2, -1, true, false, 7), 1u);
1593   EXPECT_EQ(GetFloorCount(0, 2, 3, false, false, 7), 1u);
1594 
1595   // Complete and partial tiles.
1596   EXPECT_EQ(GetFloorCount(0, 13, 1, false, false, 7), 2u);
1597   EXPECT_EQ(GetFloorCount(0, 15, 1, false, false, 7), 3u);
1598   EXPECT_EQ(GetFloorCount(-1, -14, -1, true, false, 7), 2u);
1599   EXPECT_EQ(GetFloorCount(0, 3 * 7 * 5 - 1, 3, false, false, 7), 5u);
1600   EXPECT_EQ(GetFloorCount(-1, -3 * 7 * 5, -3, true, false, 7), 5u);
1601 
1602   // Close to 16-bit integer range.
1603   EXPECT_EQ(GetFloorCount(0, 0xFFFF, 1, false, false, 1), 0xFFFFu);
1604   EXPECT_EQ(GetFloorCount(0, 0xFFFF, 1, false, false, 7), 0xFFFFu / 7 + 1);
1605   EXPECT_EQ(GetFloorCount(0, 0xFFFE, 1, false, true, 7), 0xFFFFu / 7 + 1);
1606   EXPECT_EQ(GetFloorCount(-0x8000, 0x7FFF, 1, true, false, 7), 0xFFFFu / 7 + 1);
1607   EXPECT_EQ(GetFloorCount(-0x7FFF, 0x7FFF, 1, true, true, 7), 0xFFFFu / 7 + 1);
1608   EXPECT_EQ(GetFloorCount(0, 0xFFFE, 1, false, false, 0xFFFF), 1u);
1609   EXPECT_EQ(GetFloorCount(-0x8000, 0x7FFF, 1, true, false, 0xFFFF), 1u);
1610 
1611   // Finalize the function.
1612   Builder.CreateRetVoid();
1613   OMPBuilder.finalize();
1614 
1615   EXPECT_FALSE(verifyModule(*M, &errs()));
1616 }
1617 
1618 TEST_F(OpenMPIRBuilderTest, StaticWorkShareLoop) {
1619   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1620   OpenMPIRBuilder OMPBuilder(*M);
1621   OMPBuilder.initialize();
1622   IRBuilder<> Builder(BB);
1623   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1624 
1625   Type *LCTy = Type::getInt32Ty(Ctx);
1626   Value *StartVal = ConstantInt::get(LCTy, 10);
1627   Value *StopVal = ConstantInt::get(LCTy, 52);
1628   Value *StepVal = ConstantInt::get(LCTy, 2);
1629   auto LoopBodyGen = [&](InsertPointTy, llvm::Value *) {};
1630 
1631   CanonicalLoopInfo *CLI = OMPBuilder.createCanonicalLoop(
1632       Loc, LoopBodyGen, StartVal, StopVal, StepVal,
1633       /*IsSigned=*/false, /*InclusiveStop=*/false);
1634 
1635   Builder.SetInsertPoint(BB, BB->getFirstInsertionPt());
1636   InsertPointTy AllocaIP = Builder.saveIP();
1637 
1638   CLI = OMPBuilder.createStaticWorkshareLoop(Loc, CLI, AllocaIP,
1639                                              /*NeedsBarrier=*/true);
1640   auto AllocaIter = BB->begin();
1641   ASSERT_GE(std::distance(BB->begin(), BB->end()), 4);
1642   AllocaInst *PLastIter = dyn_cast<AllocaInst>(&*(AllocaIter++));
1643   AllocaInst *PLowerBound = dyn_cast<AllocaInst>(&*(AllocaIter++));
1644   AllocaInst *PUpperBound = dyn_cast<AllocaInst>(&*(AllocaIter++));
1645   AllocaInst *PStride = dyn_cast<AllocaInst>(&*(AllocaIter++));
1646   EXPECT_NE(PLastIter, nullptr);
1647   EXPECT_NE(PLowerBound, nullptr);
1648   EXPECT_NE(PUpperBound, nullptr);
1649   EXPECT_NE(PStride, nullptr);
1650 
1651   auto PreheaderIter = CLI->getPreheader()->begin();
1652   ASSERT_GE(
1653       std::distance(CLI->getPreheader()->begin(), CLI->getPreheader()->end()),
1654       7);
1655   StoreInst *LowerBoundStore = dyn_cast<StoreInst>(&*(PreheaderIter++));
1656   StoreInst *UpperBoundStore = dyn_cast<StoreInst>(&*(PreheaderIter++));
1657   StoreInst *StrideStore = dyn_cast<StoreInst>(&*(PreheaderIter++));
1658   ASSERT_NE(LowerBoundStore, nullptr);
1659   ASSERT_NE(UpperBoundStore, nullptr);
1660   ASSERT_NE(StrideStore, nullptr);
1661 
1662   auto *OrigLowerBound =
1663       dyn_cast<ConstantInt>(LowerBoundStore->getValueOperand());
1664   auto *OrigUpperBound =
1665       dyn_cast<ConstantInt>(UpperBoundStore->getValueOperand());
1666   auto *OrigStride = dyn_cast<ConstantInt>(StrideStore->getValueOperand());
1667   ASSERT_NE(OrigLowerBound, nullptr);
1668   ASSERT_NE(OrigUpperBound, nullptr);
1669   ASSERT_NE(OrigStride, nullptr);
1670   EXPECT_EQ(OrigLowerBound->getValue(), 0);
1671   EXPECT_EQ(OrigUpperBound->getValue(), 20);
1672   EXPECT_EQ(OrigStride->getValue(), 1);
1673 
1674   // Check that the loop IV is updated to account for the lower bound returned
1675   // by the OpenMP runtime call.
1676   BinaryOperator *Add = dyn_cast<BinaryOperator>(&CLI->getBody()->front());
1677   EXPECT_EQ(Add->getOperand(0), CLI->getIndVar());
1678   auto *LoadedLowerBound = dyn_cast<LoadInst>(Add->getOperand(1));
1679   ASSERT_NE(LoadedLowerBound, nullptr);
1680   EXPECT_EQ(LoadedLowerBound->getPointerOperand(), PLowerBound);
1681 
1682   // Check that the trip count is updated to account for the lower and upper
1683   // bounds return by the OpenMP runtime call.
1684   auto *AddOne = dyn_cast<Instruction>(CLI->getTripCount());
1685   ASSERT_NE(AddOne, nullptr);
1686   ASSERT_TRUE(AddOne->isBinaryOp());
1687   auto *One = dyn_cast<ConstantInt>(AddOne->getOperand(1));
1688   ASSERT_NE(One, nullptr);
1689   EXPECT_EQ(One->getValue(), 1);
1690   auto *Difference = dyn_cast<Instruction>(AddOne->getOperand(0));
1691   ASSERT_NE(Difference, nullptr);
1692   ASSERT_TRUE(Difference->isBinaryOp());
1693   EXPECT_EQ(Difference->getOperand(1), LoadedLowerBound);
1694   auto *LoadedUpperBound = dyn_cast<LoadInst>(Difference->getOperand(0));
1695   ASSERT_NE(LoadedUpperBound, nullptr);
1696   EXPECT_EQ(LoadedUpperBound->getPointerOperand(), PUpperBound);
1697 
1698   // The original loop iterator should only be used in the condition, in the
1699   // increment and in the statement that adds the lower bound to it.
1700   Value *IV = CLI->getIndVar();
1701   EXPECT_EQ(std::distance(IV->use_begin(), IV->use_end()), 3);
1702 
1703   // The exit block should contain the "fini" call and the barrier call,
1704   // plus the call to obtain the thread ID.
1705   BasicBlock *ExitBlock = CLI->getExit();
1706   size_t NumCallsInExitBlock =
1707       count_if(*ExitBlock, [](Instruction &I) { return isa<CallInst>(I); });
1708   EXPECT_EQ(NumCallsInExitBlock, 3u);
1709 }
1710 
1711 TEST_F(OpenMPIRBuilderTest, MasterDirective) {
1712   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1713   OpenMPIRBuilder OMPBuilder(*M);
1714   OMPBuilder.initialize();
1715   F->setName("func");
1716   IRBuilder<> Builder(BB);
1717 
1718   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1719 
1720   AllocaInst *PrivAI = nullptr;
1721 
1722   BasicBlock *EntryBB = nullptr;
1723   BasicBlock *ExitBB = nullptr;
1724   BasicBlock *ThenBB = nullptr;
1725 
1726   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
1727                        BasicBlock &FiniBB) {
1728     if (AllocaIP.isSet())
1729       Builder.restoreIP(AllocaIP);
1730     else
1731       Builder.SetInsertPoint(&*(F->getEntryBlock().getFirstInsertionPt()));
1732     PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
1733     Builder.CreateStore(F->arg_begin(), PrivAI);
1734 
1735     llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1736     llvm::Instruction *CodeGenIPInst = &*CodeGenIP.getPoint();
1737     EXPECT_EQ(CodeGenIPBB->getTerminator(), CodeGenIPInst);
1738 
1739     Builder.restoreIP(CodeGenIP);
1740 
1741     // collect some info for checks later
1742     ExitBB = FiniBB.getUniqueSuccessor();
1743     ThenBB = Builder.GetInsertBlock();
1744     EntryBB = ThenBB->getUniquePredecessor();
1745 
1746     // simple instructions for body
1747     Value *PrivLoad = Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI,
1748                                          "local.use");
1749     Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
1750   };
1751 
1752   auto FiniCB = [&](InsertPointTy IP) {
1753     BasicBlock *IPBB = IP.getBlock();
1754     EXPECT_NE(IPBB->end(), IP.getPoint());
1755   };
1756 
1757   Builder.restoreIP(OMPBuilder.createMaster(Builder, BodyGenCB, FiniCB));
1758   Value *EntryBBTI = EntryBB->getTerminator();
1759   EXPECT_NE(EntryBBTI, nullptr);
1760   EXPECT_TRUE(isa<BranchInst>(EntryBBTI));
1761   BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator());
1762   EXPECT_TRUE(EntryBr->isConditional());
1763   EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB);
1764   EXPECT_EQ(ThenBB->getUniqueSuccessor(), ExitBB);
1765   EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB);
1766 
1767   CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition());
1768   EXPECT_TRUE(isa<CallInst>(CondInst->getOperand(0)));
1769 
1770   CallInst *MasterEntryCI = cast<CallInst>(CondInst->getOperand(0));
1771   EXPECT_EQ(MasterEntryCI->getNumArgOperands(), 2U);
1772   EXPECT_EQ(MasterEntryCI->getCalledFunction()->getName(), "__kmpc_master");
1773   EXPECT_TRUE(isa<GlobalVariable>(MasterEntryCI->getArgOperand(0)));
1774 
1775   CallInst *MasterEndCI = nullptr;
1776   for (auto &FI : *ThenBB) {
1777     Instruction *cur = &FI;
1778     if (isa<CallInst>(cur)) {
1779       MasterEndCI = cast<CallInst>(cur);
1780       if (MasterEndCI->getCalledFunction()->getName() == "__kmpc_end_master")
1781         break;
1782       MasterEndCI = nullptr;
1783     }
1784   }
1785   EXPECT_NE(MasterEndCI, nullptr);
1786   EXPECT_EQ(MasterEndCI->getNumArgOperands(), 2U);
1787   EXPECT_TRUE(isa<GlobalVariable>(MasterEndCI->getArgOperand(0)));
1788   EXPECT_EQ(MasterEndCI->getArgOperand(1), MasterEntryCI->getArgOperand(1));
1789 }
1790 
1791 TEST_F(OpenMPIRBuilderTest, CriticalDirective) {
1792   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1793   OpenMPIRBuilder OMPBuilder(*M);
1794   OMPBuilder.initialize();
1795   F->setName("func");
1796   IRBuilder<> Builder(BB);
1797 
1798   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1799 
1800   AllocaInst *PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
1801 
1802   BasicBlock *EntryBB = nullptr;
1803 
1804   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
1805                        BasicBlock &FiniBB) {
1806     // collect some info for checks later
1807     EntryBB = FiniBB.getUniquePredecessor();
1808 
1809     // actual start for bodyCB
1810     llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1811     llvm::Instruction *CodeGenIPInst = &*CodeGenIP.getPoint();
1812     EXPECT_EQ(CodeGenIPBB->getTerminator(), CodeGenIPInst);
1813     EXPECT_EQ(EntryBB, CodeGenIPBB);
1814 
1815     // body begin
1816     Builder.restoreIP(CodeGenIP);
1817     Builder.CreateStore(F->arg_begin(), PrivAI);
1818     Value *PrivLoad = Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI,
1819                                          "local.use");
1820     Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
1821   };
1822 
1823   auto FiniCB = [&](InsertPointTy IP) {
1824     BasicBlock *IPBB = IP.getBlock();
1825     EXPECT_NE(IPBB->end(), IP.getPoint());
1826   };
1827 
1828   Builder.restoreIP(OMPBuilder.createCritical(Builder, BodyGenCB, FiniCB,
1829                                               "testCRT", nullptr));
1830 
1831   Value *EntryBBTI = EntryBB->getTerminator();
1832   EXPECT_EQ(EntryBBTI, nullptr);
1833 
1834   CallInst *CriticalEntryCI = nullptr;
1835   for (auto &EI : *EntryBB) {
1836     Instruction *cur = &EI;
1837     if (isa<CallInst>(cur)) {
1838       CriticalEntryCI = cast<CallInst>(cur);
1839       if (CriticalEntryCI->getCalledFunction()->getName() == "__kmpc_critical")
1840         break;
1841       CriticalEntryCI = nullptr;
1842     }
1843   }
1844   EXPECT_NE(CriticalEntryCI, nullptr);
1845   EXPECT_EQ(CriticalEntryCI->getNumArgOperands(), 3U);
1846   EXPECT_EQ(CriticalEntryCI->getCalledFunction()->getName(), "__kmpc_critical");
1847   EXPECT_TRUE(isa<GlobalVariable>(CriticalEntryCI->getArgOperand(0)));
1848 
1849   CallInst *CriticalEndCI = nullptr;
1850   for (auto &FI : *EntryBB) {
1851     Instruction *cur = &FI;
1852     if (isa<CallInst>(cur)) {
1853       CriticalEndCI = cast<CallInst>(cur);
1854       if (CriticalEndCI->getCalledFunction()->getName() ==
1855           "__kmpc_end_critical")
1856         break;
1857       CriticalEndCI = nullptr;
1858     }
1859   }
1860   EXPECT_NE(CriticalEndCI, nullptr);
1861   EXPECT_EQ(CriticalEndCI->getNumArgOperands(), 3U);
1862   EXPECT_TRUE(isa<GlobalVariable>(CriticalEndCI->getArgOperand(0)));
1863   EXPECT_EQ(CriticalEndCI->getArgOperand(1), CriticalEntryCI->getArgOperand(1));
1864   PointerType *CriticalNamePtrTy =
1865       PointerType::getUnqual(ArrayType::get(Type::getInt32Ty(Ctx), 8));
1866   EXPECT_EQ(CriticalEndCI->getArgOperand(2), CriticalEntryCI->getArgOperand(2));
1867   EXPECT_EQ(CriticalEndCI->getArgOperand(2)->getType(), CriticalNamePtrTy);
1868 }
1869 
1870 TEST_F(OpenMPIRBuilderTest, CopyinBlocks) {
1871   OpenMPIRBuilder OMPBuilder(*M);
1872   OMPBuilder.initialize();
1873   F->setName("func");
1874   IRBuilder<> Builder(BB);
1875 
1876   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1877 
1878   IntegerType* Int32 = Type::getInt32Ty(M->getContext());
1879   AllocaInst* MasterAddress = Builder.CreateAlloca(Int32->getPointerTo());
1880 	AllocaInst* PrivAddress = Builder.CreateAlloca(Int32->getPointerTo());
1881 
1882   BasicBlock *EntryBB = BB;
1883 
1884   OMPBuilder.createCopyinClauseBlocks(Builder.saveIP(), MasterAddress,
1885                                       PrivAddress, Int32, /*BranchtoEnd*/ true);
1886 
1887   BranchInst* EntryBr = dyn_cast_or_null<BranchInst>(EntryBB->getTerminator());
1888 
1889   EXPECT_NE(EntryBr, nullptr);
1890   EXPECT_TRUE(EntryBr->isConditional());
1891 
1892   BasicBlock* NotMasterBB = EntryBr->getSuccessor(0);
1893   BasicBlock* CopyinEnd = EntryBr->getSuccessor(1);
1894   CmpInst* CMP = dyn_cast_or_null<CmpInst>(EntryBr->getCondition());
1895 
1896   EXPECT_NE(CMP, nullptr);
1897   EXPECT_NE(NotMasterBB, nullptr);
1898   EXPECT_NE(CopyinEnd, nullptr);
1899 
1900   BranchInst* NotMasterBr = dyn_cast_or_null<BranchInst>(NotMasterBB->getTerminator());
1901   EXPECT_NE(NotMasterBr, nullptr);
1902   EXPECT_FALSE(NotMasterBr->isConditional());
1903   EXPECT_EQ(CopyinEnd,NotMasterBr->getSuccessor(0));
1904 }
1905 
1906 TEST_F(OpenMPIRBuilderTest, SingleDirective) {
1907   using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
1908   OpenMPIRBuilder OMPBuilder(*M);
1909   OMPBuilder.initialize();
1910   F->setName("func");
1911   IRBuilder<> Builder(BB);
1912 
1913   OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
1914 
1915   AllocaInst *PrivAI = nullptr;
1916 
1917   BasicBlock *EntryBB = nullptr;
1918   BasicBlock *ExitBB = nullptr;
1919   BasicBlock *ThenBB = nullptr;
1920 
1921   auto BodyGenCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
1922                        BasicBlock &FiniBB) {
1923     if (AllocaIP.isSet())
1924       Builder.restoreIP(AllocaIP);
1925     else
1926       Builder.SetInsertPoint(&*(F->getEntryBlock().getFirstInsertionPt()));
1927     PrivAI = Builder.CreateAlloca(F->arg_begin()->getType());
1928     Builder.CreateStore(F->arg_begin(), PrivAI);
1929 
1930     llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1931     llvm::Instruction *CodeGenIPInst = &*CodeGenIP.getPoint();
1932     EXPECT_EQ(CodeGenIPBB->getTerminator(), CodeGenIPInst);
1933 
1934     Builder.restoreIP(CodeGenIP);
1935 
1936     // collect some info for checks later
1937     ExitBB = FiniBB.getUniqueSuccessor();
1938     ThenBB = Builder.GetInsertBlock();
1939     EntryBB = ThenBB->getUniquePredecessor();
1940 
1941     // simple instructions for body
1942     Value *PrivLoad = Builder.CreateLoad(PrivAI->getAllocatedType(), PrivAI,
1943                                          "local.use");
1944     Builder.CreateICmpNE(F->arg_begin(), PrivLoad);
1945   };
1946 
1947   auto FiniCB = [&](InsertPointTy IP) {
1948     BasicBlock *IPBB = IP.getBlock();
1949     EXPECT_NE(IPBB->end(), IP.getPoint());
1950   };
1951 
1952   Builder.restoreIP(
1953       OMPBuilder.createSingle(Builder, BodyGenCB, FiniCB, /*DidIt*/ nullptr));
1954   Value *EntryBBTI = EntryBB->getTerminator();
1955   EXPECT_NE(EntryBBTI, nullptr);
1956   EXPECT_TRUE(isa<BranchInst>(EntryBBTI));
1957   BranchInst *EntryBr = cast<BranchInst>(EntryBB->getTerminator());
1958   EXPECT_TRUE(EntryBr->isConditional());
1959   EXPECT_EQ(EntryBr->getSuccessor(0), ThenBB);
1960   EXPECT_EQ(ThenBB->getUniqueSuccessor(), ExitBB);
1961   EXPECT_EQ(EntryBr->getSuccessor(1), ExitBB);
1962 
1963   CmpInst *CondInst = cast<CmpInst>(EntryBr->getCondition());
1964   EXPECT_TRUE(isa<CallInst>(CondInst->getOperand(0)));
1965 
1966   CallInst *SingleEntryCI = cast<CallInst>(CondInst->getOperand(0));
1967   EXPECT_EQ(SingleEntryCI->getNumArgOperands(), 2U);
1968   EXPECT_EQ(SingleEntryCI->getCalledFunction()->getName(), "__kmpc_single");
1969   EXPECT_TRUE(isa<GlobalVariable>(SingleEntryCI->getArgOperand(0)));
1970 
1971   CallInst *SingleEndCI = nullptr;
1972   for (auto &FI : *ThenBB) {
1973     Instruction *cur = &FI;
1974     if (isa<CallInst>(cur)) {
1975       SingleEndCI = cast<CallInst>(cur);
1976       if (SingleEndCI->getCalledFunction()->getName() == "__kmpc_end_single")
1977         break;
1978       SingleEndCI = nullptr;
1979     }
1980   }
1981   EXPECT_NE(SingleEndCI, nullptr);
1982   EXPECT_EQ(SingleEndCI->getNumArgOperands(), 2U);
1983   EXPECT_TRUE(isa<GlobalVariable>(SingleEndCI->getArgOperand(0)));
1984   EXPECT_EQ(SingleEndCI->getArgOperand(1), SingleEntryCI->getArgOperand(1));
1985 }
1986 
1987 } // namespace
1988