[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / Transforms / Utils / LoopUtilsTest.cpp
blobaa0d72cf8bb33e4b4fc76e1262ee4749b1048144
1 //===- LoopUtilsTest.cpp - Unit tests for LoopUtils -----------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/LoopUtils.h"
10 #include "llvm/Analysis/AssumptionCache.h"
11 #include "llvm/Analysis/LoopInfo.h"
12 #include "llvm/Analysis/ScalarEvolution.h"
13 #include "llvm/Analysis/TargetLibraryInfo.h"
14 #include "llvm/AsmParser/Parser.h"
15 #include "llvm/IR/Dominators.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
19 using namespace llvm;
21 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
22 SMDiagnostic Err;
23 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
24 if (!Mod)
25 Err.print("LoopUtilsTests", errs());
26 return Mod;
29 static void run(Module &M, StringRef FuncName,
30 function_ref<void(Function &F, DominatorTree &DT,
31 ScalarEvolution &SE, LoopInfo &LI)>
32 Test) {
33 Function *F = M.getFunction(FuncName);
34 DominatorTree DT(*F);
35 TargetLibraryInfoImpl TLII;
36 TargetLibraryInfo TLI(TLII);
37 AssumptionCache AC(*F);
38 LoopInfo LI(DT);
39 ScalarEvolution SE(*F, TLI, AC, DT, LI);
40 Test(*F, DT, SE, LI);
43 TEST(LoopUtils, DeleteDeadLoopNest) {
44 LLVMContext C;
45 std::unique_ptr<Module> M =
46 parseIR(C, "define void @foo() {\n"
47 "entry:\n"
48 " br label %for.i\n"
49 "for.i:\n"
50 " %i = phi i64 [ 0, %entry ], [ %inc.i, %for.i.latch ]\n"
51 " br label %for.j\n"
52 "for.j:\n"
53 " %j = phi i64 [ 0, %for.i ], [ %inc.j, %for.j ]\n"
54 " %inc.j = add nsw i64 %j, 1\n"
55 " %cmp.j = icmp slt i64 %inc.j, 100\n"
56 " br i1 %cmp.j, label %for.j, label %for.k.preheader\n"
57 "for.k.preheader:\n"
58 " br label %for.k\n"
59 "for.k:\n"
60 " %k = phi i64 [ %inc.k, %for.k ], [ 0, %for.k.preheader ]\n"
61 " %inc.k = add nsw i64 %k, 1\n"
62 " %cmp.k = icmp slt i64 %inc.k, 100\n"
63 " br i1 %cmp.k, label %for.k, label %for.i.latch\n"
64 "for.i.latch:\n"
65 " %inc.i = add nsw i64 %i, 1\n"
66 " %cmp.i = icmp slt i64 %inc.i, 100\n"
67 " br i1 %cmp.i, label %for.i, label %for.end\n"
68 "for.end:\n"
69 " ret void\n"
70 "}\n");
72 run(*M, "foo",
73 [&](Function &F, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI) {
74 assert(LI.begin() != LI.end() && "Expecting loops in function F");
75 Loop *L = *LI.begin();
76 assert(L && L->getName() == "for.i" && "Expecting loop for.i");
78 deleteDeadLoop(L, &DT, &SE, &LI);
80 assert(DT.verify(DominatorTree::VerificationLevel::Fast) &&
81 "Expecting valid dominator tree");
82 LI.verify(DT);
83 assert(LI.begin() == LI.end() &&
84 "Expecting no loops left in function F");
85 SE.verify();
87 Function::iterator FI = F.begin();
88 BasicBlock *Entry = &*(FI++);
89 assert(Entry->getName() == "entry" && "Expecting BasicBlock entry");
90 const BranchInst *BI = dyn_cast<BranchInst>(Entry->getTerminator());
91 assert(BI && "Expecting valid branch instruction");
92 EXPECT_EQ(BI->getNumSuccessors(), (unsigned)1);
93 EXPECT_EQ(BI->getSuccessor(0)->getName(), "for.end");
94 });