1 //===- LoopNestTest.cpp - LoopNestAnalysis unit 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/Analysis/LoopNestAnalysis.h"
10 #include "llvm/Analysis/ScalarEvolution.h"
11 #include "llvm/Analysis/TargetLibraryInfo.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
19 /// Build the loop nest analysis for a loop nest and run the given test \p Test.
20 static void runTest(
21     Module &M, StringRef FuncName,
22     function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE)> Test) {
23   auto *F = M.getFunction(FuncName);
24   ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
25 
26   TargetLibraryInfoImpl TLII;
27   TargetLibraryInfo TLI(TLII);
28   AssumptionCache AC(*F);
29   DominatorTree DT(*F);
30   LoopInfo LI(DT);
31   ScalarEvolution SE(*F, TLI, AC, DT, LI);
32 
33   Test(*F, LI, SE);
34 }
35 
36 static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
37                                               const char *ModuleStr) {
38   SMDiagnostic Err;
39   return parseAssemblyString(ModuleStr, Err, Context);
40 }
41 
42 TEST(LoopNestTest, PerfectLoopNest) {
43   const char *ModuleStr =
44     "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
45     "define void @foo(i64 signext %nx, i64 signext %ny) {\n"
46     "entry:\n"
47     "  br label %for.outer\n"
48     "for.outer:\n"
49     "  %i = phi i64 [ 0, %entry ], [ %inc13, %for.outer.latch ]\n"
50     "  %cmp21 = icmp slt i64 0, %ny\n"
51     "  br i1 %cmp21, label %for.inner.preheader, label %for.outer.latch\n"
52     "for.inner.preheader:\n"
53     "  br label %for.inner\n"
54     "for.inner:\n"
55     "  %j = phi i64 [ 0, %for.inner.preheader ], [ %inc, %for.inner.latch ]\n"
56     "  br label %for.inner.latch\n"
57     "for.inner.latch:\n"
58     "  %inc = add nsw i64 %j, 1\n"
59     "  %cmp2 = icmp slt i64 %inc, %ny\n"
60     "  br i1 %cmp2, label %for.inner, label %for.inner.exit\n"
61     "for.inner.exit:\n"
62     "  br label %for.outer.latch\n"
63     "for.outer.latch:\n"
64     "  %inc13 = add nsw i64 %i, 1\n"
65     "  %cmp = icmp slt i64 %inc13, %nx\n"
66     "  br i1 %cmp, label %for.outer, label %for.outer.exit\n"
67     "for.outer.exit:\n"
68     "  br label %for.end\n"
69     "for.end:\n"
70     "  ret void\n"
71     "}\n";
72 
73   LLVMContext Context;
74   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
75 
76   runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
77     Function::iterator FI = F.begin();
78     // Skip the first basic block (entry), get to the outer loop header.
79     BasicBlock *Header = &*(++FI);
80     assert(Header->getName() == "for.outer");
81     Loop *L = LI.getLoopFor(Header);
82     EXPECT_NE(L, nullptr);
83 
84     LoopNest LN(*L, SE);
85     EXPECT_TRUE(LN.areAllLoopsSimplifyForm());
86 
87     // Ensure that we can identify the outermost loop in the nest.
88     const Loop &OL = LN.getOutermostLoop();
89     EXPECT_EQ(OL.getName(), "for.outer");
90 
91     // Ensure that we can identify the innermost loop in the nest.
92     const Loop *IL = LN.getInnermostLoop();
93     EXPECT_NE(IL, nullptr);
94     EXPECT_EQ(IL->getName(), "for.inner");
95 
96     // Ensure the loop nest is recognized as having 2 loops.
97     const ArrayRef<Loop*> Loops = LN.getLoops();
98     EXPECT_EQ(Loops.size(), 2ull);
99 
100     // Ensure the loop nest is recognized as perfect in its entirety.
101     const SmallVector<LoopVectorTy, 4> &PLV = LN.getPerfectLoops(SE);
102     EXPECT_EQ(PLV.size(), 1ull);
103     EXPECT_EQ(PLV.front().size(), 2ull);
104 
105     // Ensure the nest depth and perfect nest depth are computed correctly.
106     EXPECT_EQ(LN.getNestDepth(), 2u);
107     EXPECT_EQ(LN.getMaxPerfectDepth(), 2u);
108   });
109 }
110 
111 TEST(LoopNestTest, ImperfectLoopNest) {
112   const char *ModuleStr =
113       "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
114       "define void @foo(i32 signext %nx, i32 signext %ny, i32 signext %nk) {\n"
115       "entry:\n"
116       "  br label %loop.i\n"
117       "loop.i:\n"
118       "  %i = phi i32 [ 0, %entry ], [ %inci, %for.inci ]\n"
119       "  %cmp21 = icmp slt i32 0, %ny\n"
120       "  br i1 %cmp21, label %loop.j.preheader, label %for.inci\n"
121       "loop.j.preheader:\n"
122       "  br label %loop.j\n"
123       "loop.j:\n"
124       "  %j = phi i32 [ %incj, %for.incj ], [ 0, %loop.j.preheader ]\n"
125       "  %cmp22 = icmp slt i32 0, %nk\n"
126       "  br i1 %cmp22, label %loop.k.preheader, label %for.incj\n"
127       "loop.k.preheader:\n"
128       "  call void @bar()\n"
129       "  br label %loop.k\n"
130       "loop.k:\n"
131       "  %k = phi i32 [ %inck, %for.inck ], [ 0, %loop.k.preheader ]\n"
132       "  br label %for.inck\n"
133       "for.inck:\n"
134       "  %inck = add nsw i32 %k, 1\n"
135       "  %cmp5 = icmp slt i32 %inck, %nk\n"
136       "  br i1 %cmp5, label %loop.k, label %for.incj.loopexit\n"
137       "for.incj.loopexit:\n"
138       "  br label %for.incj\n"
139       "for.incj:\n"
140       "  %incj = add nsw i32 %j, 1\n"
141       "  %cmp2 = icmp slt i32 %incj, %ny\n"
142       "  br i1 %cmp2, label %loop.j, label %for.inci.loopexit\n"
143       "for.inci.loopexit:\n"
144       "  br label %for.inci\n"
145       "for.inci:\n"
146       "  %inci = add nsw i32 %i, 1\n"
147       "  %cmp = icmp slt i32 %inci, %nx\n"
148       "  br i1 %cmp, label %loop.i, label %loop.i.end\n"
149       "loop.i.end:\n"
150       "  ret void\n"
151       "}\n"
152       "declare void @bar()\n";
153 
154   LLVMContext Context;
155   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
156 
157   runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
158     Function::iterator FI = F.begin();
159     // Skip the first basic block (entry), get to the outermost loop header.
160     BasicBlock *Header = &*(++FI);
161     assert(Header->getName() == "loop.i");
162     Loop *L = LI.getLoopFor(Header);
163     EXPECT_NE(L, nullptr);
164 
165     LoopNest LN(*L, SE);
166     EXPECT_TRUE(LN.areAllLoopsSimplifyForm());
167 
168     dbgs() << "LN: " << LN << "\n";
169 
170     // Ensure that we can identify the outermost loop in the nest.
171     const Loop &OL = LN.getOutermostLoop();
172     EXPECT_EQ(OL.getName(), "loop.i");
173 
174     // Ensure that we can identify the innermost loop in the nest.
175     const Loop *IL = LN.getInnermostLoop();
176     EXPECT_NE(IL, nullptr);
177     EXPECT_EQ(IL->getName(), "loop.k");
178 
179     // Ensure the loop nest is recognized as having 3 loops.
180     const ArrayRef<Loop*> Loops = LN.getLoops();
181     EXPECT_EQ(Loops.size(), 3ull);
182 
183     // Ensure the loop nest is recognized as having 2 separate perfect loops groups.
184     const SmallVector<LoopVectorTy, 4> &PLV = LN.getPerfectLoops(SE);
185     EXPECT_EQ(PLV.size(), 2ull);
186     EXPECT_EQ(PLV.front().size(), 2ull);
187     EXPECT_EQ(PLV.back().size(), 1ull);
188 
189     // Ensure the nest depth and perfect nest depth are computed correctly.
190     EXPECT_EQ(LN.getNestDepth(), 3u);
191     EXPECT_EQ(LN.getMaxPerfectDepth(), 2u);
192   });
193 }
194 
195