xref: /llvm-project/llvm/unittests/Analysis/LoopNestTest.cpp (revision 4169338e75cdce73d34063532db598c95ee82ae4)
1c84532a7SWhitney Tsang //===- LoopNestTest.cpp - LoopNestAnalysis unit tests ---------------------===//
2c84532a7SWhitney Tsang //
3c84532a7SWhitney Tsang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c84532a7SWhitney Tsang // See https://llvm.org/LICENSE.txt for license information.
5c84532a7SWhitney Tsang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c84532a7SWhitney Tsang //
7c84532a7SWhitney Tsang //===----------------------------------------------------------------------===//
8c84532a7SWhitney Tsang 
95006e551SSimon Pilgrim #include "llvm/Analysis/AssumptionCache.h"
10c84532a7SWhitney Tsang #include "llvm/Analysis/LoopNestAnalysis.h"
11c84532a7SWhitney Tsang #include "llvm/Analysis/ScalarEvolution.h"
12c84532a7SWhitney Tsang #include "llvm/Analysis/TargetLibraryInfo.h"
13c84532a7SWhitney Tsang #include "llvm/AsmParser/Parser.h"
14c84532a7SWhitney Tsang #include "llvm/IR/Dominators.h"
15*4169338eSNikita Popov #include "llvm/IR/Module.h"
16c84532a7SWhitney Tsang #include "llvm/Support/SourceMgr.h"
17c84532a7SWhitney Tsang #include "gtest/gtest.h"
18c84532a7SWhitney Tsang 
19c84532a7SWhitney Tsang using namespace llvm;
20c84532a7SWhitney Tsang 
21c84532a7SWhitney Tsang /// Build the loop nest analysis for a loop nest and run the given test \p Test.
runTest(Module & M,StringRef FuncName,function_ref<void (Function & F,LoopInfo & LI,ScalarEvolution & SE)> Test)22c84532a7SWhitney Tsang static void runTest(
23c84532a7SWhitney Tsang     Module &M, StringRef FuncName,
24c84532a7SWhitney Tsang     function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE)> Test) {
25c84532a7SWhitney Tsang   auto *F = M.getFunction(FuncName);
26c84532a7SWhitney Tsang   ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
27c84532a7SWhitney Tsang 
28c84532a7SWhitney Tsang   TargetLibraryInfoImpl TLII;
29c84532a7SWhitney Tsang   TargetLibraryInfo TLI(TLII);
30c84532a7SWhitney Tsang   AssumptionCache AC(*F);
31c84532a7SWhitney Tsang   DominatorTree DT(*F);
32c84532a7SWhitney Tsang   LoopInfo LI(DT);
33c84532a7SWhitney Tsang   ScalarEvolution SE(*F, TLI, AC, DT, LI);
34c84532a7SWhitney Tsang 
35c84532a7SWhitney Tsang   Test(*F, LI, SE);
36c84532a7SWhitney Tsang }
37c84532a7SWhitney Tsang 
makeLLVMModule(LLVMContext & Context,const char * ModuleStr)38c84532a7SWhitney Tsang static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
39c84532a7SWhitney Tsang                                               const char *ModuleStr) {
40c84532a7SWhitney Tsang   SMDiagnostic Err;
41c84532a7SWhitney Tsang   return parseAssemblyString(ModuleStr, Err, Context);
42c84532a7SWhitney Tsang }
43c84532a7SWhitney Tsang 
getInstructionByName(Function & F,StringRef Name)444018d25dSMark Danial static Instruction *getInstructionByName(Function &F, StringRef Name) {
454018d25dSMark Danial   for (BasicBlock &BB : F)
464018d25dSMark Danial     for (Instruction &I : BB)
474018d25dSMark Danial       if (I.getName() == Name)
484018d25dSMark Danial         return &I;
494018d25dSMark Danial   llvm_unreachable("Expected to find instruction!");
504018d25dSMark Danial }
514018d25dSMark Danial 
TEST(LoopNestTest,PerfectLoopNest)52c84532a7SWhitney Tsang TEST(LoopNestTest, PerfectLoopNest) {
53c84532a7SWhitney Tsang   const char *ModuleStr =
54c84532a7SWhitney Tsang     "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
55c84532a7SWhitney Tsang     "define void @foo(i64 signext %nx, i64 signext %ny) {\n"
56c84532a7SWhitney Tsang     "entry:\n"
57c84532a7SWhitney Tsang     "  br label %for.outer\n"
58c84532a7SWhitney Tsang     "for.outer:\n"
59c84532a7SWhitney Tsang     "  %i = phi i64 [ 0, %entry ], [ %inc13, %for.outer.latch ]\n"
60c84532a7SWhitney Tsang     "  %cmp21 = icmp slt i64 0, %ny\n"
61c84532a7SWhitney Tsang     "  br i1 %cmp21, label %for.inner.preheader, label %for.outer.latch\n"
62c84532a7SWhitney Tsang     "for.inner.preheader:\n"
63c84532a7SWhitney Tsang     "  br label %for.inner\n"
64c84532a7SWhitney Tsang     "for.inner:\n"
65c84532a7SWhitney Tsang     "  %j = phi i64 [ 0, %for.inner.preheader ], [ %inc, %for.inner.latch ]\n"
66c84532a7SWhitney Tsang     "  br label %for.inner.latch\n"
67c84532a7SWhitney Tsang     "for.inner.latch:\n"
68c84532a7SWhitney Tsang     "  %inc = add nsw i64 %j, 1\n"
69c84532a7SWhitney Tsang     "  %cmp2 = icmp slt i64 %inc, %ny\n"
70c84532a7SWhitney Tsang     "  br i1 %cmp2, label %for.inner, label %for.inner.exit\n"
71c84532a7SWhitney Tsang     "for.inner.exit:\n"
72c84532a7SWhitney Tsang     "  br label %for.outer.latch\n"
73c84532a7SWhitney Tsang     "for.outer.latch:\n"
74c84532a7SWhitney Tsang     "  %inc13 = add nsw i64 %i, 1\n"
75c84532a7SWhitney Tsang     "  %cmp = icmp slt i64 %inc13, %nx\n"
76c84532a7SWhitney Tsang     "  br i1 %cmp, label %for.outer, label %for.outer.exit\n"
77c84532a7SWhitney Tsang     "for.outer.exit:\n"
78c84532a7SWhitney Tsang     "  br label %for.end\n"
79c84532a7SWhitney Tsang     "for.end:\n"
80c84532a7SWhitney Tsang     "  ret void\n"
81c84532a7SWhitney Tsang     "}\n";
82c84532a7SWhitney Tsang 
83c84532a7SWhitney Tsang   LLVMContext Context;
84c84532a7SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
85c84532a7SWhitney Tsang 
86c84532a7SWhitney Tsang   runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
87c84532a7SWhitney Tsang     Function::iterator FI = F.begin();
88c84532a7SWhitney Tsang     // Skip the first basic block (entry), get to the outer loop header.
89c84532a7SWhitney Tsang     BasicBlock *Header = &*(++FI);
90c84532a7SWhitney Tsang     assert(Header->getName() == "for.outer");
91c84532a7SWhitney Tsang     Loop *L = LI.getLoopFor(Header);
92c84532a7SWhitney Tsang     EXPECT_NE(L, nullptr);
93c84532a7SWhitney Tsang 
94c84532a7SWhitney Tsang     LoopNest LN(*L, SE);
95c84532a7SWhitney Tsang     EXPECT_TRUE(LN.areAllLoopsSimplifyForm());
96c84532a7SWhitney Tsang 
97c84532a7SWhitney Tsang     // Ensure that we can identify the outermost loop in the nest.
98c84532a7SWhitney Tsang     const Loop &OL = LN.getOutermostLoop();
99c84532a7SWhitney Tsang     EXPECT_EQ(OL.getName(), "for.outer");
100c84532a7SWhitney Tsang 
101c84532a7SWhitney Tsang     // Ensure that we can identify the innermost loop in the nest.
102c84532a7SWhitney Tsang     const Loop *IL = LN.getInnermostLoop();
103c84532a7SWhitney Tsang     EXPECT_NE(IL, nullptr);
104c84532a7SWhitney Tsang     EXPECT_EQ(IL->getName(), "for.inner");
105c84532a7SWhitney Tsang 
106c84532a7SWhitney Tsang     // Ensure the loop nest is recognized as having 2 loops.
107c84532a7SWhitney Tsang     const ArrayRef<Loop*> Loops = LN.getLoops();
108c84532a7SWhitney Tsang     EXPECT_EQ(Loops.size(), 2ull);
109c84532a7SWhitney Tsang 
110cb6b9d3aSWhitney Tsang     // Ensure that we can obtain loops by depth.
111cb6b9d3aSWhitney Tsang     LoopVectorTy LoopsAtDepth1 = LN.getLoopsAtDepth(1);
112cb6b9d3aSWhitney Tsang     EXPECT_EQ(LoopsAtDepth1.size(), 1u);
113cb6b9d3aSWhitney Tsang     EXPECT_EQ(LoopsAtDepth1[0], &OL);
114cb6b9d3aSWhitney Tsang     LoopVectorTy LoopsAtDepth2 = LN.getLoopsAtDepth(2);
115cb6b9d3aSWhitney Tsang     EXPECT_EQ(LoopsAtDepth2.size(), 1u);
116cb6b9d3aSWhitney Tsang     EXPECT_EQ(LoopsAtDepth2[0], IL);
117cb6b9d3aSWhitney Tsang 
118cb6b9d3aSWhitney Tsang     // Ensure that we can obtain the loop index of a given loop, and get back
119cb6b9d3aSWhitney Tsang     // the loop with that index.
120cb6b9d3aSWhitney Tsang     EXPECT_EQ(LN.getLoop(LN.getLoopIndex(OL)), &OL);
121cb6b9d3aSWhitney Tsang     EXPECT_EQ(LN.getLoop(LN.getLoopIndex(*IL)), IL);
122cb6b9d3aSWhitney Tsang 
123c84532a7SWhitney Tsang     // Ensure the loop nest is recognized as perfect in its entirety.
124c84532a7SWhitney Tsang     const SmallVector<LoopVectorTy, 4> &PLV = LN.getPerfectLoops(SE);
125c84532a7SWhitney Tsang     EXPECT_EQ(PLV.size(), 1ull);
126c84532a7SWhitney Tsang     EXPECT_EQ(PLV.front().size(), 2ull);
127c84532a7SWhitney Tsang 
128c84532a7SWhitney Tsang     // Ensure the nest depth and perfect nest depth are computed correctly.
129c84532a7SWhitney Tsang     EXPECT_EQ(LN.getNestDepth(), 2u);
130c84532a7SWhitney Tsang     EXPECT_EQ(LN.getMaxPerfectDepth(), 2u);
1314018d25dSMark Danial 
1324018d25dSMark Danial     EXPECT_TRUE(LN.getInterveningInstructions(OL, *IL, SE).empty());
133c84532a7SWhitney Tsang   });
134c84532a7SWhitney Tsang }
135c84532a7SWhitney Tsang 
TEST(LoopNestTest,ImperfectLoopNest)136c84532a7SWhitney Tsang TEST(LoopNestTest, ImperfectLoopNest) {
137c84532a7SWhitney Tsang   const char *ModuleStr =
138c84532a7SWhitney Tsang       "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
139c84532a7SWhitney Tsang       "define void @foo(i32 signext %nx, i32 signext %ny, i32 signext %nk) {\n"
140c84532a7SWhitney Tsang       "entry:\n"
141c84532a7SWhitney Tsang       "  br label %loop.i\n"
142c84532a7SWhitney Tsang       "loop.i:\n"
143c84532a7SWhitney Tsang       "  %i = phi i32 [ 0, %entry ], [ %inci, %for.inci ]\n"
144c84532a7SWhitney Tsang       "  %cmp21 = icmp slt i32 0, %ny\n"
145c84532a7SWhitney Tsang       "  br i1 %cmp21, label %loop.j.preheader, label %for.inci\n"
146c84532a7SWhitney Tsang       "loop.j.preheader:\n"
147c84532a7SWhitney Tsang       "  br label %loop.j\n"
148c84532a7SWhitney Tsang       "loop.j:\n"
149c84532a7SWhitney Tsang       "  %j = phi i32 [ %incj, %for.incj ], [ 0, %loop.j.preheader ]\n"
150c84532a7SWhitney Tsang       "  %cmp22 = icmp slt i32 0, %nk\n"
151c84532a7SWhitney Tsang       "  br i1 %cmp22, label %loop.k.preheader, label %for.incj\n"
152c84532a7SWhitney Tsang       "loop.k.preheader:\n"
153c84532a7SWhitney Tsang       "  call void @bar()\n"
154c84532a7SWhitney Tsang       "  br label %loop.k\n"
155c84532a7SWhitney Tsang       "loop.k:\n"
156c84532a7SWhitney Tsang       "  %k = phi i32 [ %inck, %for.inck ], [ 0, %loop.k.preheader ]\n"
157c84532a7SWhitney Tsang       "  br label %for.inck\n"
158c84532a7SWhitney Tsang       "for.inck:\n"
159c84532a7SWhitney Tsang       "  %inck = add nsw i32 %k, 1\n"
160c84532a7SWhitney Tsang       "  %cmp5 = icmp slt i32 %inck, %nk\n"
161c84532a7SWhitney Tsang       "  br i1 %cmp5, label %loop.k, label %for.incj.loopexit\n"
162c84532a7SWhitney Tsang       "for.incj.loopexit:\n"
163c84532a7SWhitney Tsang       "  br label %for.incj\n"
164c84532a7SWhitney Tsang       "for.incj:\n"
165c84532a7SWhitney Tsang       "  %incj = add nsw i32 %j, 1\n"
166c84532a7SWhitney Tsang       "  %cmp2 = icmp slt i32 %incj, %ny\n"
167c84532a7SWhitney Tsang       "  br i1 %cmp2, label %loop.j, label %for.inci.loopexit\n"
168c84532a7SWhitney Tsang       "for.inci.loopexit:\n"
169c84532a7SWhitney Tsang       "  br label %for.inci\n"
170c84532a7SWhitney Tsang       "for.inci:\n"
171c84532a7SWhitney Tsang       "  %inci = add nsw i32 %i, 1\n"
172c84532a7SWhitney Tsang       "  %cmp = icmp slt i32 %inci, %nx\n"
173c84532a7SWhitney Tsang       "  br i1 %cmp, label %loop.i, label %loop.i.end\n"
174c84532a7SWhitney Tsang       "loop.i.end:\n"
175c84532a7SWhitney Tsang       "  ret void\n"
176c84532a7SWhitney Tsang       "}\n"
177c84532a7SWhitney Tsang       "declare void @bar()\n";
178c84532a7SWhitney Tsang 
179c84532a7SWhitney Tsang   LLVMContext Context;
180c84532a7SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
181c84532a7SWhitney Tsang 
182c84532a7SWhitney Tsang   runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
183c84532a7SWhitney Tsang     Function::iterator FI = F.begin();
184c84532a7SWhitney Tsang     // Skip the first basic block (entry), get to the outermost loop header.
185c84532a7SWhitney Tsang     BasicBlock *Header = &*(++FI);
186c84532a7SWhitney Tsang     assert(Header->getName() == "loop.i");
187c84532a7SWhitney Tsang     Loop *L = LI.getLoopFor(Header);
188c84532a7SWhitney Tsang     EXPECT_NE(L, nullptr);
189c84532a7SWhitney Tsang 
190c84532a7SWhitney Tsang     LoopNest LN(*L, SE);
191c84532a7SWhitney Tsang     EXPECT_TRUE(LN.areAllLoopsSimplifyForm());
192c84532a7SWhitney Tsang 
193c84532a7SWhitney Tsang     dbgs() << "LN: " << LN << "\n";
194c84532a7SWhitney Tsang 
195c84532a7SWhitney Tsang     // Ensure that we can identify the outermost loop in the nest.
196c84532a7SWhitney Tsang     const Loop &OL = LN.getOutermostLoop();
197c84532a7SWhitney Tsang     EXPECT_EQ(OL.getName(), "loop.i");
198c84532a7SWhitney Tsang 
199c84532a7SWhitney Tsang     // Ensure that we can identify the innermost loop in the nest.
200c84532a7SWhitney Tsang     const Loop *IL = LN.getInnermostLoop();
201c84532a7SWhitney Tsang     EXPECT_NE(IL, nullptr);
202c84532a7SWhitney Tsang     EXPECT_EQ(IL->getName(), "loop.k");
203c84532a7SWhitney Tsang 
204c84532a7SWhitney Tsang     // Ensure the loop nest is recognized as having 3 loops.
205c84532a7SWhitney Tsang     const ArrayRef<Loop*> Loops = LN.getLoops();
206c84532a7SWhitney Tsang     EXPECT_EQ(Loops.size(), 3ull);
207c84532a7SWhitney Tsang 
208c84532a7SWhitney Tsang     // Ensure the loop nest is recognized as having 2 separate perfect loops groups.
209c84532a7SWhitney Tsang     const SmallVector<LoopVectorTy, 4> &PLV = LN.getPerfectLoops(SE);
210c84532a7SWhitney Tsang     EXPECT_EQ(PLV.size(), 2ull);
211c84532a7SWhitney Tsang     EXPECT_EQ(PLV.front().size(), 2ull);
212c84532a7SWhitney Tsang     EXPECT_EQ(PLV.back().size(), 1ull);
213c84532a7SWhitney Tsang 
214c84532a7SWhitney Tsang     // Ensure the nest depth and perfect nest depth are computed correctly.
215c84532a7SWhitney Tsang     EXPECT_EQ(LN.getNestDepth(), 3u);
216c84532a7SWhitney Tsang     EXPECT_EQ(LN.getMaxPerfectDepth(), 2u);
2174018d25dSMark Danial 
2184018d25dSMark Danial     EXPECT_TRUE(LN.getInterveningInstructions(OL, *IL, SE).empty());
219c84532a7SWhitney Tsang   });
220c84532a7SWhitney Tsang }
221c84532a7SWhitney Tsang 
TEST(LoopNestTest,InterveningInstrLoopNest)2224018d25dSMark Danial TEST(LoopNestTest, InterveningInstrLoopNest) {
2234018d25dSMark Danial   const char *ModuleStr =
2244018d25dSMark Danial       "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
2254018d25dSMark Danial       "define void @foo(i64 signext %nx, i64 signext %ny, i32* noalias %A, i32 "
2264018d25dSMark Danial       "%op0, i32 %op1){\n"
2274018d25dSMark Danial       "entry:\n"
2284018d25dSMark Danial       "  br label %for.outer\n"
2294018d25dSMark Danial       "for.outer:\n"
2304018d25dSMark Danial       "  %i = phi i64 [ 0, %entry ], [ %inc13, %for.outer.latch ]\n"
2314018d25dSMark Danial       "  %cmp21 = icmp slt i64 0, %ny\n"
2324018d25dSMark Danial       "  call void @outerheader()\n"
2334018d25dSMark Danial       "  br i1 %cmp21, label %for.inner.preheader, label %for.outer.latch\n"
2344018d25dSMark Danial       "for.inner.preheader:\n"
2354018d25dSMark Danial       "  %varr = getelementptr inbounds i32, i32* %A, i64 5\n"
2364018d25dSMark Danial       "  store i32 5, i32* %varr, align 4\n"
2374018d25dSMark Danial       "  call void @innerpreheader()\n"
2384018d25dSMark Danial       "  br label %for.inner\n"
2394018d25dSMark Danial       "for.inner:\n"
2404018d25dSMark Danial       "  %j = phi i64 [ 0, %for.inner.preheader ], [ %inc, %for.inner.latch ]\n"
2414018d25dSMark Danial       "  br label %for.inner.latch\n"
2424018d25dSMark Danial       "for.inner.latch:\n"
2434018d25dSMark Danial       "  %inc = add nsw i64 %j, 1\n"
2444018d25dSMark Danial       "  %cmp2 = icmp slt i64 %inc, %ny\n"
2454018d25dSMark Danial       "  br i1 %cmp2, label %for.inner, label %for.inner.exit\n"
2464018d25dSMark Danial       "for.inner.exit:\n"
2474018d25dSMark Danial       "  %varr1 = getelementptr inbounds i32, i32* %A, i64 5\n"
2484018d25dSMark Danial       "  call void @innerexit()\n"
2494018d25dSMark Danial       "  br label %for.outer.latch\n"
2504018d25dSMark Danial       "for.outer.latch:\n"
2514018d25dSMark Danial       "  %inc13 = add nsw i64 %i, 1\n"
2524018d25dSMark Danial       "  call void @outerlatch()\n"
2534018d25dSMark Danial       "  %cmp = icmp slt i64 %inc13, %nx\n"
2544018d25dSMark Danial       "  br i1 %cmp, label %for.outer, label %for.outer.exit\n"
2554018d25dSMark Danial       "for.outer.exit:\n"
2564018d25dSMark Danial       "  br label %for.end\n"
2574018d25dSMark Danial       "for.end:\n"
2584018d25dSMark Danial       "  ret void\n"
2594018d25dSMark Danial       "}\n"
2604018d25dSMark Danial       "declare void @innerpreheader()\n"
2614018d25dSMark Danial       "declare void @outerheader()\n"
2624018d25dSMark Danial       "declare void @outerlatch()\n"
2634018d25dSMark Danial       "declare void @innerexit()\n";
2644018d25dSMark Danial 
2654018d25dSMark Danial   LLVMContext Context;
2664018d25dSMark Danial   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
2674018d25dSMark Danial 
2684018d25dSMark Danial   runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
2694018d25dSMark Danial     Function::iterator FI = F.begin();
2704018d25dSMark Danial     // Skip the first basic block (entry), get to the outer loop header.
2714018d25dSMark Danial     BasicBlock *Header = &*(++FI);
2724018d25dSMark Danial     assert(Header->getName() == "for.outer");
2734018d25dSMark Danial     Loop *L = LI.getLoopFor(Header);
2744018d25dSMark Danial     EXPECT_NE(L, nullptr);
2754018d25dSMark Danial 
2764018d25dSMark Danial     LoopNest LN(*L, SE);
2774018d25dSMark Danial     EXPECT_TRUE(LN.areAllLoopsSimplifyForm());
2784018d25dSMark Danial 
2794018d25dSMark Danial     // Ensure that we can identify the outermost loop in the nest.
2804018d25dSMark Danial     const Loop &OL = LN.getOutermostLoop();
2814018d25dSMark Danial     EXPECT_EQ(OL.getName(), "for.outer");
2824018d25dSMark Danial 
2834018d25dSMark Danial     // Ensure that we can identify the innermost loop in the nest.
2844018d25dSMark Danial     const Loop *IL = LN.getInnermostLoop();
2854018d25dSMark Danial     EXPECT_NE(IL, nullptr);
2864018d25dSMark Danial     EXPECT_EQ(IL->getName(), "for.inner");
2874018d25dSMark Danial 
2884018d25dSMark Danial     // Ensure the loop nest is recognized as having 2 loops.
2894018d25dSMark Danial     const ArrayRef<Loop *> Loops = LN.getLoops();
2904018d25dSMark Danial     EXPECT_EQ(Loops.size(), 2ull);
2914018d25dSMark Danial 
2924018d25dSMark Danial     // Ensure the loop nest is not recognized as perfect in its entirety.
2934018d25dSMark Danial     const SmallVector<LoopVectorTy, 4> &PLV = LN.getPerfectLoops(SE);
2944018d25dSMark Danial     EXPECT_EQ(PLV.size(), 2ull);
2954018d25dSMark Danial     EXPECT_EQ(PLV.front().size(), 1ull);
2964018d25dSMark Danial     EXPECT_EQ(PLV.back().size(), 1ull);
2974018d25dSMark Danial 
2984018d25dSMark Danial     // Ensure the nest depth and perfect nest depth are computed correctly.
2994018d25dSMark Danial     EXPECT_EQ(LN.getNestDepth(), 2u);
3004018d25dSMark Danial     EXPECT_EQ(LN.getMaxPerfectDepth(), 1u);
3014018d25dSMark Danial 
3024018d25dSMark Danial     // Ensure enclosed instructions are recognized
3034018d25dSMark Danial     const LoopNest::InstrVectorTy InstrV =
3044018d25dSMark Danial         LN.getInterveningInstructions(OL, *IL, SE);
3054018d25dSMark Danial     EXPECT_EQ(InstrV.size(), 5u);
3064018d25dSMark Danial 
3074018d25dSMark Danial     Instruction *SI = getInstructionByName(F, "varr")->getNextNode();
3084018d25dSMark Danial     Instruction *CI = SI->getNextNode();
3094018d25dSMark Danial     Instruction *OLH =
3104018d25dSMark Danial         getInstructionByName(F, "i")->getNextNode()->getNextNode();
3114018d25dSMark Danial     Instruction *OLL = getInstructionByName(F, "inc13")->getNextNode();
3124018d25dSMark Danial     Instruction *IE = getInstructionByName(F, "varr1")->getNextNode();
3134018d25dSMark Danial 
3144018d25dSMark Danial     EXPECT_EQ(InstrV.front(), OLH);
3154018d25dSMark Danial     EXPECT_EQ(InstrV[1], OLL);
3164018d25dSMark Danial     EXPECT_EQ(InstrV[2], IE);
3174018d25dSMark Danial     EXPECT_EQ(InstrV[3], SI);
3184018d25dSMark Danial     EXPECT_EQ(InstrV.back(), CI);
3194018d25dSMark Danial   });
3204018d25dSMark Danial }
321