1ca02360fSXin Tong //===- LoopInfoTest.cpp - LoopInfo unit tests -----------------------------===//
2ca02360fSXin Tong //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ca02360fSXin Tong //
7ca02360fSXin Tong //===----------------------------------------------------------------------===//
8ca02360fSXin Tong 
9ca02360fSXin Tong #include "llvm/Analysis/LoopInfo.h"
10*2d0896c1SWhitney Tsang #include "llvm/Analysis/AssumptionCache.h"
11*2d0896c1SWhitney Tsang #include "llvm/Analysis/PostDominators.h"
12*2d0896c1SWhitney Tsang #include "llvm/Analysis/ScalarEvolution.h"
13*2d0896c1SWhitney Tsang #include "llvm/Analysis/TargetLibraryInfo.h"
14ca02360fSXin Tong #include "llvm/AsmParser/Parser.h"
15ca02360fSXin Tong #include "llvm/IR/Dominators.h"
16ca02360fSXin Tong #include "llvm/Support/SourceMgr.h"
17ca02360fSXin Tong #include "gtest/gtest.h"
18ca02360fSXin Tong 
19ca02360fSXin Tong using namespace llvm;
20ca02360fSXin Tong 
2143c1a264SXin Tong /// Build the loop info for the function and run the Test.
2243c1a264SXin Tong static void
2343c1a264SXin Tong runWithLoopInfo(Module &M, StringRef FuncName,
2443c1a264SXin Tong                 function_ref<void(Function &F, LoopInfo &LI)> Test) {
2543c1a264SXin Tong   auto *F = M.getFunction(FuncName);
2643c1a264SXin Tong   ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
2743c1a264SXin Tong   // Compute the dominator tree and the loop info for the function.
2843c1a264SXin Tong   DominatorTree DT(*F);
2943c1a264SXin Tong   LoopInfo LI(DT);
3043c1a264SXin Tong   Test(*F, LI);
3143c1a264SXin Tong }
3243c1a264SXin Tong 
33*2d0896c1SWhitney Tsang /// Build the loop info and scalar evolution for the function and run the Test.
34*2d0896c1SWhitney Tsang static void runWithLoopInfoPlus(
35*2d0896c1SWhitney Tsang     Module &M, StringRef FuncName,
36*2d0896c1SWhitney Tsang     function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE,
37*2d0896c1SWhitney Tsang                       PostDominatorTree &PDT)>
38*2d0896c1SWhitney Tsang         Test) {
39*2d0896c1SWhitney Tsang   auto *F = M.getFunction(FuncName);
40*2d0896c1SWhitney Tsang   ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
41*2d0896c1SWhitney Tsang 
42*2d0896c1SWhitney Tsang   TargetLibraryInfoImpl TLII;
43*2d0896c1SWhitney Tsang   TargetLibraryInfo TLI(TLII);
44*2d0896c1SWhitney Tsang   AssumptionCache AC(*F);
45*2d0896c1SWhitney Tsang   DominatorTree DT(*F);
46*2d0896c1SWhitney Tsang   LoopInfo LI(DT);
47*2d0896c1SWhitney Tsang   ScalarEvolution SE(*F, TLI, AC, DT, LI);
48*2d0896c1SWhitney Tsang 
49*2d0896c1SWhitney Tsang   PostDominatorTree PDT(*F);
50*2d0896c1SWhitney Tsang   Test(*F, LI, SE, PDT);
51*2d0896c1SWhitney Tsang }
52*2d0896c1SWhitney Tsang 
53ca02360fSXin Tong static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
54ca02360fSXin Tong                                               const char *ModuleStr) {
55ca02360fSXin Tong   SMDiagnostic Err;
56ca02360fSXin Tong   return parseAssemblyString(ModuleStr, Err, Context);
57ca02360fSXin Tong }
58ca02360fSXin Tong 
59ca02360fSXin Tong // This tests that for a loop with a single latch, we get the loop id from
60ca02360fSXin Tong // its only latch, even in case the loop may not be in a simplified form.
61ca02360fSXin Tong TEST(LoopInfoTest, LoopWithSingleLatch) {
62ca02360fSXin Tong   const char *ModuleStr =
63ca02360fSXin Tong       "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
64ca02360fSXin Tong       "define void @foo(i32 %n) {\n"
65ca02360fSXin Tong       "entry:\n"
66ca02360fSXin Tong       "  br i1 undef, label %for.cond, label %for.end\n"
67ca02360fSXin Tong       "for.cond:\n"
68ca02360fSXin Tong       "  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
69ca02360fSXin Tong       "  %cmp = icmp slt i32 %i.0, %n\n"
70ca02360fSXin Tong       "  br i1 %cmp, label %for.inc, label %for.end\n"
71ca02360fSXin Tong       "for.inc:\n"
72ca02360fSXin Tong       "  %inc = add nsw i32 %i.0, 1\n"
73ca02360fSXin Tong       "  br label %for.cond, !llvm.loop !0\n"
74ca02360fSXin Tong       "for.end:\n"
75ca02360fSXin Tong       "  ret void\n"
76ca02360fSXin Tong       "}\n"
77ca02360fSXin Tong       "!0 = distinct !{!0, !1}\n"
78ca02360fSXin Tong       "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
79ca02360fSXin Tong 
80ca02360fSXin Tong   // Parse the module.
81ca02360fSXin Tong   LLVMContext Context;
82ca02360fSXin Tong   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
83ca02360fSXin Tong 
8443c1a264SXin Tong   runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
85ca02360fSXin Tong     Function::iterator FI = F.begin();
8643c1a264SXin Tong     // First basic block is entry - skip it.
8743c1a264SXin Tong     BasicBlock *Header = &*(++FI);
88ca02360fSXin Tong     assert(Header->getName() == "for.cond");
89ca02360fSXin Tong     Loop *L = LI.getLoopFor(Header);
90ca02360fSXin Tong 
91ca02360fSXin Tong     // This loop is not in simplified form.
92ca02360fSXin Tong     EXPECT_FALSE(L->isLoopSimplifyForm());
93ca02360fSXin Tong 
94ca02360fSXin Tong     // Analyze the loop metadata id.
95ca02360fSXin Tong     bool loopIDFoundAndSet = false;
96ca02360fSXin Tong     // Try to get and set the metadata id for the loop.
97ca02360fSXin Tong     if (MDNode *D = L->getLoopID()) {
98ca02360fSXin Tong       L->setLoopID(D);
99ca02360fSXin Tong       loopIDFoundAndSet = true;
100ca02360fSXin Tong     }
101ca02360fSXin Tong 
102ca02360fSXin Tong     // We must have successfully found and set the loop id in the
103ca02360fSXin Tong     // only latch the loop has.
104ca02360fSXin Tong     EXPECT_TRUE(loopIDFoundAndSet);
10543c1a264SXin Tong   });
106ca02360fSXin Tong }
107f002264dSChandler Carruth 
108a58e9214SJohannes Doerfert // Test loop id handling for a loop with multiple latches.
109a58e9214SJohannes Doerfert TEST(LoopInfoTest, LoopWithMultipleLatches) {
110a58e9214SJohannes Doerfert   const char *ModuleStr =
111a58e9214SJohannes Doerfert       "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
112a58e9214SJohannes Doerfert       "define void @foo(i32 %n) {\n"
113a58e9214SJohannes Doerfert       "entry:\n"
114a58e9214SJohannes Doerfert       "  br i1 undef, label %for.cond, label %for.end\n"
115a58e9214SJohannes Doerfert       "for.cond:\n"
116a58e9214SJohannes Doerfert       "  %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n"
117a58e9214SJohannes Doerfert       "  %inc = add nsw i32 %i.0, 1\n"
118a58e9214SJohannes Doerfert       "  %cmp = icmp slt i32 %i.0, %n\n"
119a58e9214SJohannes Doerfert       "  br i1 %cmp, label %latch.1, label %for.end\n"
120a58e9214SJohannes Doerfert       "latch.1:\n"
121a58e9214SJohannes Doerfert       "  br i1 undef, label %for.cond, label %latch.2, !llvm.loop !0\n"
122a58e9214SJohannes Doerfert       "latch.2:\n"
123a58e9214SJohannes Doerfert       "  br label %for.cond, !llvm.loop !0\n"
124a58e9214SJohannes Doerfert       "for.end:\n"
125a58e9214SJohannes Doerfert       "  ret void\n"
126a58e9214SJohannes Doerfert       "}\n"
127a58e9214SJohannes Doerfert       "!0 = distinct !{!0, !1}\n"
128a58e9214SJohannes Doerfert       "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
129a58e9214SJohannes Doerfert 
130a58e9214SJohannes Doerfert   // Parse the module.
131a58e9214SJohannes Doerfert   LLVMContext Context;
132a58e9214SJohannes Doerfert   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
133a58e9214SJohannes Doerfert 
134a58e9214SJohannes Doerfert   runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
135a58e9214SJohannes Doerfert     Function::iterator FI = F.begin();
136a58e9214SJohannes Doerfert     // First basic block is entry - skip it.
137a58e9214SJohannes Doerfert     BasicBlock *Header = &*(++FI);
138a58e9214SJohannes Doerfert     assert(Header->getName() == "for.cond");
139a58e9214SJohannes Doerfert     Loop *L = LI.getLoopFor(Header);
140a58e9214SJohannes Doerfert     EXPECT_NE(L, nullptr);
141a58e9214SJohannes Doerfert 
142a58e9214SJohannes Doerfert     // This loop is not in simplified form.
143a58e9214SJohannes Doerfert     EXPECT_FALSE(L->isLoopSimplifyForm());
144a58e9214SJohannes Doerfert 
145a58e9214SJohannes Doerfert     // Try to get and set the metadata id for the loop.
146a58e9214SJohannes Doerfert     MDNode *OldLoopID = L->getLoopID();
147a58e9214SJohannes Doerfert     EXPECT_NE(OldLoopID, nullptr);
148a58e9214SJohannes Doerfert 
149a58e9214SJohannes Doerfert     MDNode *NewLoopID = MDNode::get(Context, {nullptr});
150a58e9214SJohannes Doerfert     // Set operand 0 to refer to the loop id itself.
151a58e9214SJohannes Doerfert     NewLoopID->replaceOperandWith(0, NewLoopID);
152a58e9214SJohannes Doerfert 
153a58e9214SJohannes Doerfert     L->setLoopID(NewLoopID);
154a58e9214SJohannes Doerfert     EXPECT_EQ(L->getLoopID(), NewLoopID);
155a58e9214SJohannes Doerfert     EXPECT_NE(L->getLoopID(), OldLoopID);
156a58e9214SJohannes Doerfert 
157a58e9214SJohannes Doerfert     L->setLoopID(OldLoopID);
158a58e9214SJohannes Doerfert     EXPECT_EQ(L->getLoopID(), OldLoopID);
159a58e9214SJohannes Doerfert     EXPECT_NE(L->getLoopID(), NewLoopID);
160a58e9214SJohannes Doerfert   });
161a58e9214SJohannes Doerfert }
162a58e9214SJohannes Doerfert 
163f002264dSChandler Carruth TEST(LoopInfoTest, PreorderTraversals) {
164f002264dSChandler Carruth   const char *ModuleStr = "define void @f() {\n"
165f002264dSChandler Carruth                           "entry:\n"
166f002264dSChandler Carruth                           "  br label %loop.0\n"
167f002264dSChandler Carruth                           "loop.0:\n"
168f002264dSChandler Carruth                           "  br i1 undef, label %loop.0.0, label %loop.1\n"
169f002264dSChandler Carruth                           "loop.0.0:\n"
170f002264dSChandler Carruth                           "  br i1 undef, label %loop.0.0, label %loop.0.1\n"
171f002264dSChandler Carruth                           "loop.0.1:\n"
172f002264dSChandler Carruth                           "  br i1 undef, label %loop.0.1, label %loop.0.2\n"
173f002264dSChandler Carruth                           "loop.0.2:\n"
174f002264dSChandler Carruth                           "  br i1 undef, label %loop.0.2, label %loop.0\n"
175f002264dSChandler Carruth                           "loop.1:\n"
176f002264dSChandler Carruth                           "  br i1 undef, label %loop.1.0, label %end\n"
177f002264dSChandler Carruth                           "loop.1.0:\n"
178f002264dSChandler Carruth                           "  br i1 undef, label %loop.1.0, label %loop.1.1\n"
179f002264dSChandler Carruth                           "loop.1.1:\n"
180f002264dSChandler Carruth                           "  br i1 undef, label %loop.1.1, label %loop.1.2\n"
181f002264dSChandler Carruth                           "loop.1.2:\n"
182f002264dSChandler Carruth                           "  br i1 undef, label %loop.1.2, label %loop.1\n"
183f002264dSChandler Carruth                           "end:\n"
184f002264dSChandler Carruth                           "  ret void\n"
185f002264dSChandler Carruth                           "}\n";
186f002264dSChandler Carruth   // Parse the module.
187f002264dSChandler Carruth   LLVMContext Context;
188f002264dSChandler Carruth   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
189f002264dSChandler Carruth   Function &F = *M->begin();
190f002264dSChandler Carruth 
191f002264dSChandler Carruth   DominatorTree DT(F);
192f002264dSChandler Carruth   LoopInfo LI;
193f002264dSChandler Carruth   LI.analyze(DT);
194f002264dSChandler Carruth 
195f002264dSChandler Carruth   Function::iterator I = F.begin();
196f002264dSChandler Carruth   ASSERT_EQ("entry", I->getName());
197f002264dSChandler Carruth   ++I;
198f002264dSChandler Carruth   Loop &L_0 = *LI.getLoopFor(&*I++);
199f002264dSChandler Carruth   ASSERT_EQ("loop.0", L_0.getHeader()->getName());
200f002264dSChandler Carruth   Loop &L_0_0 = *LI.getLoopFor(&*I++);
201f002264dSChandler Carruth   ASSERT_EQ("loop.0.0", L_0_0.getHeader()->getName());
202f002264dSChandler Carruth   Loop &L_0_1 = *LI.getLoopFor(&*I++);
203f002264dSChandler Carruth   ASSERT_EQ("loop.0.1", L_0_1.getHeader()->getName());
204f002264dSChandler Carruth   Loop &L_0_2 = *LI.getLoopFor(&*I++);
205f002264dSChandler Carruth   ASSERT_EQ("loop.0.2", L_0_2.getHeader()->getName());
206f002264dSChandler Carruth   Loop &L_1 = *LI.getLoopFor(&*I++);
207f002264dSChandler Carruth   ASSERT_EQ("loop.1", L_1.getHeader()->getName());
208f002264dSChandler Carruth   Loop &L_1_0 = *LI.getLoopFor(&*I++);
209f002264dSChandler Carruth   ASSERT_EQ("loop.1.0", L_1_0.getHeader()->getName());
210f002264dSChandler Carruth   Loop &L_1_1 = *LI.getLoopFor(&*I++);
211f002264dSChandler Carruth   ASSERT_EQ("loop.1.1", L_1_1.getHeader()->getName());
212f002264dSChandler Carruth   Loop &L_1_2 = *LI.getLoopFor(&*I++);
213f002264dSChandler Carruth   ASSERT_EQ("loop.1.2", L_1_2.getHeader()->getName());
214f002264dSChandler Carruth 
215f002264dSChandler Carruth   auto Preorder = LI.getLoopsInPreorder();
216f002264dSChandler Carruth   ASSERT_EQ(8u, Preorder.size());
217f002264dSChandler Carruth   EXPECT_EQ(&L_0, Preorder[0]);
218f002264dSChandler Carruth   EXPECT_EQ(&L_0_0, Preorder[1]);
219f002264dSChandler Carruth   EXPECT_EQ(&L_0_1, Preorder[2]);
220f002264dSChandler Carruth   EXPECT_EQ(&L_0_2, Preorder[3]);
221f002264dSChandler Carruth   EXPECT_EQ(&L_1, Preorder[4]);
222f002264dSChandler Carruth   EXPECT_EQ(&L_1_0, Preorder[5]);
223f002264dSChandler Carruth   EXPECT_EQ(&L_1_1, Preorder[6]);
224f002264dSChandler Carruth   EXPECT_EQ(&L_1_2, Preorder[7]);
225f002264dSChandler Carruth 
226f002264dSChandler Carruth   auto ReverseSiblingPreorder = LI.getLoopsInReverseSiblingPreorder();
227f002264dSChandler Carruth   ASSERT_EQ(8u, ReverseSiblingPreorder.size());
228f002264dSChandler Carruth   EXPECT_EQ(&L_1, ReverseSiblingPreorder[0]);
229f002264dSChandler Carruth   EXPECT_EQ(&L_1_2, ReverseSiblingPreorder[1]);
230f002264dSChandler Carruth   EXPECT_EQ(&L_1_1, ReverseSiblingPreorder[2]);
231f002264dSChandler Carruth   EXPECT_EQ(&L_1_0, ReverseSiblingPreorder[3]);
232f002264dSChandler Carruth   EXPECT_EQ(&L_0, ReverseSiblingPreorder[4]);
233f002264dSChandler Carruth   EXPECT_EQ(&L_0_2, ReverseSiblingPreorder[5]);
234f002264dSChandler Carruth   EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]);
235f002264dSChandler Carruth   EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]);
236f002264dSChandler Carruth }
237*2d0896c1SWhitney Tsang 
238*2d0896c1SWhitney Tsang TEST(LoopInfoTest, CanonicalLoop) {
239*2d0896c1SWhitney Tsang   const char *ModuleStr =
240*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
241*2d0896c1SWhitney Tsang       "entry:\n"
242*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
243*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
244*2d0896c1SWhitney Tsang       "for.preheader:\n"
245*2d0896c1SWhitney Tsang       "  br label %for.body\n"
246*2d0896c1SWhitney Tsang       "for.body:\n"
247*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
248*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
249*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
250*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
251*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
252*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
253*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
254*2d0896c1SWhitney Tsang       "for.exit:\n"
255*2d0896c1SWhitney Tsang       "  br label %for.end\n"
256*2d0896c1SWhitney Tsang       "for.end:\n"
257*2d0896c1SWhitney Tsang       "  ret void\n"
258*2d0896c1SWhitney Tsang       "}\n";
259*2d0896c1SWhitney Tsang 
260*2d0896c1SWhitney Tsang   // Parse the module.
261*2d0896c1SWhitney Tsang   LLVMContext Context;
262*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
263*2d0896c1SWhitney Tsang 
264*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
265*2d0896c1SWhitney Tsang       *M, "foo",
266*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
267*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
268*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
269*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
270*2d0896c1SWhitney Tsang         ++FI;
271*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
272*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
273*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
274*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
275*2d0896c1SWhitney Tsang 
276*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
277*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
278*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
279*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
280*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
281*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
282*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
283*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
284*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
285*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
286*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
287*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
288*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
289*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
290*2d0896c1SWhitney Tsang       });
291*2d0896c1SWhitney Tsang }
292*2d0896c1SWhitney Tsang 
293*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopWithInverseGuardSuccs) {
294*2d0896c1SWhitney Tsang   const char *ModuleStr =
295*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
296*2d0896c1SWhitney Tsang       "entry:\n"
297*2d0896c1SWhitney Tsang       "  %guardcmp = icmp sge i32 0, %ub\n"
298*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.end, label %for.preheader\n"
299*2d0896c1SWhitney Tsang       "for.preheader:\n"
300*2d0896c1SWhitney Tsang       "  br label %for.body\n"
301*2d0896c1SWhitney Tsang       "for.body:\n"
302*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
303*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
304*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
305*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
306*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
307*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
308*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
309*2d0896c1SWhitney Tsang       "for.exit:\n"
310*2d0896c1SWhitney Tsang       "  br label %for.end\n"
311*2d0896c1SWhitney Tsang       "for.end:\n"
312*2d0896c1SWhitney Tsang       "  ret void\n"
313*2d0896c1SWhitney Tsang       "}\n";
314*2d0896c1SWhitney Tsang 
315*2d0896c1SWhitney Tsang   // Parse the module.
316*2d0896c1SWhitney Tsang   LLVMContext Context;
317*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
318*2d0896c1SWhitney Tsang 
319*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
320*2d0896c1SWhitney Tsang       *M, "foo",
321*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
322*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
323*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
324*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
325*2d0896c1SWhitney Tsang         ++FI;
326*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
327*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
328*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
329*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
330*2d0896c1SWhitney Tsang 
331*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
332*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
333*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
334*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
335*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
336*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
337*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
338*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
339*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
340*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
341*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
342*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
343*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
344*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
345*2d0896c1SWhitney Tsang       });
346*2d0896c1SWhitney Tsang }
347*2d0896c1SWhitney Tsang 
348*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopWithSwappedGuardCmp) {
349*2d0896c1SWhitney Tsang   const char *ModuleStr =
350*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
351*2d0896c1SWhitney Tsang       "entry:\n"
352*2d0896c1SWhitney Tsang       "  %guardcmp = icmp sgt i32 %ub, 0\n"
353*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
354*2d0896c1SWhitney Tsang       "for.preheader:\n"
355*2d0896c1SWhitney Tsang       "  br label %for.body\n"
356*2d0896c1SWhitney Tsang       "for.body:\n"
357*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
358*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
359*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
360*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
361*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
362*2d0896c1SWhitney Tsang       "  %cmp = icmp sge i32 %inc, %ub\n"
363*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.exit, label %for.body\n"
364*2d0896c1SWhitney Tsang       "for.exit:\n"
365*2d0896c1SWhitney Tsang       "  br label %for.end\n"
366*2d0896c1SWhitney Tsang       "for.end:\n"
367*2d0896c1SWhitney Tsang       "  ret void\n"
368*2d0896c1SWhitney Tsang       "}\n";
369*2d0896c1SWhitney Tsang 
370*2d0896c1SWhitney Tsang   // Parse the module.
371*2d0896c1SWhitney Tsang   LLVMContext Context;
372*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
373*2d0896c1SWhitney Tsang 
374*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
375*2d0896c1SWhitney Tsang       *M, "foo",
376*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
377*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
378*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
379*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
380*2d0896c1SWhitney Tsang         ++FI;
381*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
382*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
383*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
384*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
385*2d0896c1SWhitney Tsang 
386*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
387*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
388*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
389*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
390*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
391*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
392*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
393*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
394*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
395*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
396*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
397*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
398*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
399*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
400*2d0896c1SWhitney Tsang       });
401*2d0896c1SWhitney Tsang }
402*2d0896c1SWhitney Tsang 
403*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopWithInverseLatchSuccs) {
404*2d0896c1SWhitney Tsang   const char *ModuleStr =
405*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
406*2d0896c1SWhitney Tsang       "entry:\n"
407*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
408*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
409*2d0896c1SWhitney Tsang       "for.preheader:\n"
410*2d0896c1SWhitney Tsang       "  br label %for.body\n"
411*2d0896c1SWhitney Tsang       "for.body:\n"
412*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
413*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
414*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
415*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
416*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
417*2d0896c1SWhitney Tsang       "  %cmp = icmp sge i32 %inc, %ub\n"
418*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.exit, label %for.body\n"
419*2d0896c1SWhitney Tsang       "for.exit:\n"
420*2d0896c1SWhitney Tsang       "  br label %for.end\n"
421*2d0896c1SWhitney Tsang       "for.end:\n"
422*2d0896c1SWhitney Tsang       "  ret void\n"
423*2d0896c1SWhitney Tsang       "}\n";
424*2d0896c1SWhitney Tsang 
425*2d0896c1SWhitney Tsang   // Parse the module.
426*2d0896c1SWhitney Tsang   LLVMContext Context;
427*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
428*2d0896c1SWhitney Tsang 
429*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
430*2d0896c1SWhitney Tsang       *M, "foo",
431*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
432*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
433*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
434*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
435*2d0896c1SWhitney Tsang         ++FI;
436*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
437*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
438*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
439*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
440*2d0896c1SWhitney Tsang 
441*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
442*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
443*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
444*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
445*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
446*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
447*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
448*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
449*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
450*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
451*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
452*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
453*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
454*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
455*2d0896c1SWhitney Tsang       });
456*2d0896c1SWhitney Tsang }
457*2d0896c1SWhitney Tsang 
458*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopWithLatchCmpNE) {
459*2d0896c1SWhitney Tsang   const char *ModuleStr =
460*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
461*2d0896c1SWhitney Tsang       "entry:\n"
462*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
463*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
464*2d0896c1SWhitney Tsang       "for.preheader:\n"
465*2d0896c1SWhitney Tsang       "  br label %for.body\n"
466*2d0896c1SWhitney Tsang       "for.body:\n"
467*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
468*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
469*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
470*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
471*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
472*2d0896c1SWhitney Tsang       "  %cmp = icmp ne i32 %i, %ub\n"
473*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
474*2d0896c1SWhitney Tsang       "for.exit:\n"
475*2d0896c1SWhitney Tsang       "  br label %for.end\n"
476*2d0896c1SWhitney Tsang       "for.end:\n"
477*2d0896c1SWhitney Tsang       "  ret void\n"
478*2d0896c1SWhitney Tsang       "}\n";
479*2d0896c1SWhitney Tsang 
480*2d0896c1SWhitney Tsang   // Parse the module.
481*2d0896c1SWhitney Tsang   LLVMContext Context;
482*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
483*2d0896c1SWhitney Tsang 
484*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
485*2d0896c1SWhitney Tsang       *M, "foo",
486*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
487*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
488*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
489*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
490*2d0896c1SWhitney Tsang         ++FI;
491*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
492*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
493*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
494*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
495*2d0896c1SWhitney Tsang 
496*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
497*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
498*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
499*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
500*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
501*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
502*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
503*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
504*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
505*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
506*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
507*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
508*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
509*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
510*2d0896c1SWhitney Tsang       });
511*2d0896c1SWhitney Tsang }
512*2d0896c1SWhitney Tsang 
513*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopWithGuardCmpSLE) {
514*2d0896c1SWhitney Tsang   const char *ModuleStr =
515*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
516*2d0896c1SWhitney Tsang       "entry:\n"
517*2d0896c1SWhitney Tsang       "  %ubPlusOne = add i32 %ub, 1\n"
518*2d0896c1SWhitney Tsang       "  %guardcmp = icmp sle i32 0, %ub\n"
519*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
520*2d0896c1SWhitney Tsang       "for.preheader:\n"
521*2d0896c1SWhitney Tsang       "  br label %for.body\n"
522*2d0896c1SWhitney Tsang       "for.body:\n"
523*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
524*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
525*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
526*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
527*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
528*2d0896c1SWhitney Tsang       "  %cmp = icmp ne i32 %i, %ubPlusOne\n"
529*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
530*2d0896c1SWhitney Tsang       "for.exit:\n"
531*2d0896c1SWhitney Tsang       "  br label %for.end\n"
532*2d0896c1SWhitney Tsang       "for.end:\n"
533*2d0896c1SWhitney Tsang       "  ret void\n"
534*2d0896c1SWhitney Tsang       "}\n";
535*2d0896c1SWhitney Tsang 
536*2d0896c1SWhitney Tsang   // Parse the module.
537*2d0896c1SWhitney Tsang   LLVMContext Context;
538*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
539*2d0896c1SWhitney Tsang 
540*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
541*2d0896c1SWhitney Tsang       *M, "foo",
542*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
543*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
544*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
545*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
546*2d0896c1SWhitney Tsang         ++FI;
547*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
548*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
549*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
550*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
551*2d0896c1SWhitney Tsang 
552*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
553*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
554*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
555*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
556*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
557*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
558*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
559*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
560*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
561*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ubPlusOne");
562*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
563*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
564*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
565*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
566*2d0896c1SWhitney Tsang       });
567*2d0896c1SWhitney Tsang }
568*2d0896c1SWhitney Tsang 
569*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopNonConstantStep) {
570*2d0896c1SWhitney Tsang   const char *ModuleStr =
571*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
572*2d0896c1SWhitney Tsang       "entry:\n"
573*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
574*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
575*2d0896c1SWhitney Tsang       "for.preheader:\n"
576*2d0896c1SWhitney Tsang       "  br label %for.body\n"
577*2d0896c1SWhitney Tsang       "for.body:\n"
578*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
579*2d0896c1SWhitney Tsang       "  %idxprom = zext i32 %i to i64\n"
580*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
581*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
582*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, %step\n"
583*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
584*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
585*2d0896c1SWhitney Tsang       "for.exit:\n"
586*2d0896c1SWhitney Tsang       "  br label %for.end\n"
587*2d0896c1SWhitney Tsang       "for.end:\n"
588*2d0896c1SWhitney Tsang       "  ret void\n"
589*2d0896c1SWhitney Tsang       "}\n";
590*2d0896c1SWhitney Tsang 
591*2d0896c1SWhitney Tsang   // Parse the module.
592*2d0896c1SWhitney Tsang   LLVMContext Context;
593*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
594*2d0896c1SWhitney Tsang 
595*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
596*2d0896c1SWhitney Tsang       *M, "foo",
597*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
598*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
599*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
600*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
601*2d0896c1SWhitney Tsang         ++FI;
602*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
603*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
604*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
605*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
606*2d0896c1SWhitney Tsang 
607*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
608*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
609*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
610*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
611*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
612*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
613*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
614*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
615*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
616*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(), Loop::LoopBounds::Direction::Unknown);
617*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
618*2d0896c1SWhitney Tsang       });
619*2d0896c1SWhitney Tsang }
620*2d0896c1SWhitney Tsang 
621*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopUnsignedBounds) {
622*2d0896c1SWhitney Tsang   const char *ModuleStr =
623*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
624*2d0896c1SWhitney Tsang       "entry:\n"
625*2d0896c1SWhitney Tsang       "  %guardcmp = icmp ult i32 0, %ub\n"
626*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
627*2d0896c1SWhitney Tsang       "for.preheader:\n"
628*2d0896c1SWhitney Tsang       "  br label %for.body\n"
629*2d0896c1SWhitney Tsang       "for.body:\n"
630*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
631*2d0896c1SWhitney Tsang       "  %idxprom = zext i32 %i to i64\n"
632*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
633*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
634*2d0896c1SWhitney Tsang       "  %inc = add i32 %i, 1\n"
635*2d0896c1SWhitney Tsang       "  %cmp = icmp ult i32 %inc, %ub\n"
636*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
637*2d0896c1SWhitney Tsang       "for.exit:\n"
638*2d0896c1SWhitney Tsang       "  br label %for.end\n"
639*2d0896c1SWhitney Tsang       "for.end:\n"
640*2d0896c1SWhitney Tsang       "  ret void\n"
641*2d0896c1SWhitney Tsang       "}\n";
642*2d0896c1SWhitney Tsang 
643*2d0896c1SWhitney Tsang   // Parse the module.
644*2d0896c1SWhitney Tsang   LLVMContext Context;
645*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
646*2d0896c1SWhitney Tsang 
647*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
648*2d0896c1SWhitney Tsang       *M, "foo",
649*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
650*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
651*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
652*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
653*2d0896c1SWhitney Tsang         ++FI;
654*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
655*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
656*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
657*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
658*2d0896c1SWhitney Tsang 
659*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
660*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
661*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
662*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
663*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
664*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
665*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
666*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
667*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
668*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
669*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_ULT);
670*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
671*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
672*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
673*2d0896c1SWhitney Tsang       });
674*2d0896c1SWhitney Tsang }
675*2d0896c1SWhitney Tsang 
676*2d0896c1SWhitney Tsang TEST(LoopInfoTest, DecreasingLoop) {
677*2d0896c1SWhitney Tsang   const char *ModuleStr =
678*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
679*2d0896c1SWhitney Tsang       "entry:\n"
680*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
681*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
682*2d0896c1SWhitney Tsang       "for.preheader:\n"
683*2d0896c1SWhitney Tsang       "  br label %for.body\n"
684*2d0896c1SWhitney Tsang       "for.body:\n"
685*2d0896c1SWhitney Tsang       "  %i = phi i32 [ %ub, %for.preheader ], [ %inc, %for.body ]\n"
686*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
687*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
688*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
689*2d0896c1SWhitney Tsang       "  %inc = sub nsw i32 %i, 1\n"
690*2d0896c1SWhitney Tsang       "  %cmp = icmp sgt i32 %inc, 0\n"
691*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
692*2d0896c1SWhitney Tsang       "for.exit:\n"
693*2d0896c1SWhitney Tsang       "  br label %for.end\n"
694*2d0896c1SWhitney Tsang       "for.end:\n"
695*2d0896c1SWhitney Tsang       "  ret void\n"
696*2d0896c1SWhitney Tsang       "}\n";
697*2d0896c1SWhitney Tsang 
698*2d0896c1SWhitney Tsang   // Parse the module.
699*2d0896c1SWhitney Tsang   LLVMContext Context;
700*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
701*2d0896c1SWhitney Tsang 
702*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
703*2d0896c1SWhitney Tsang       *M, "foo",
704*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
705*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
706*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
707*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
708*2d0896c1SWhitney Tsang         ++FI;
709*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
710*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
711*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
712*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
713*2d0896c1SWhitney Tsang 
714*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
715*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
716*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getInitialIVValue().getName(), "ub");
717*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
718*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
719*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
720*2d0896c1SWhitney Tsang         EXPECT_EQ(StepValue, nullptr);
721*2d0896c1SWhitney Tsang         ConstantInt *FinalIVValue =
722*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getFinalIVValue());
723*2d0896c1SWhitney Tsang         EXPECT_TRUE(FinalIVValue && FinalIVValue->isZero());
724*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SGT);
725*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
726*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Decreasing);
727*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
728*2d0896c1SWhitney Tsang       });
729*2d0896c1SWhitney Tsang }
730*2d0896c1SWhitney Tsang 
731*2d0896c1SWhitney Tsang TEST(LoopInfoTest, CannotFindDirection) {
732*2d0896c1SWhitney Tsang   const char *ModuleStr =
733*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
734*2d0896c1SWhitney Tsang       "entry:\n"
735*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
736*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
737*2d0896c1SWhitney Tsang       "for.preheader:\n"
738*2d0896c1SWhitney Tsang       "  br label %for.body\n"
739*2d0896c1SWhitney Tsang       "for.body:\n"
740*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
741*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
742*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
743*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
744*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, %step\n"
745*2d0896c1SWhitney Tsang       "  %cmp = icmp ne i32 %i, %ub\n"
746*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
747*2d0896c1SWhitney Tsang       "for.exit:\n"
748*2d0896c1SWhitney Tsang       "  br label %for.end\n"
749*2d0896c1SWhitney Tsang       "for.end:\n"
750*2d0896c1SWhitney Tsang       "  ret void\n"
751*2d0896c1SWhitney Tsang       "}\n";
752*2d0896c1SWhitney Tsang 
753*2d0896c1SWhitney Tsang   // Parse the module.
754*2d0896c1SWhitney Tsang   LLVMContext Context;
755*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
756*2d0896c1SWhitney Tsang 
757*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(*M, "foo",
758*2d0896c1SWhitney Tsang                       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
759*2d0896c1SWhitney Tsang                           PostDominatorTree &PDT) {
760*2d0896c1SWhitney Tsang                         Function::iterator FI = F.begin();
761*2d0896c1SWhitney Tsang                         // First two basic block are entry and for.preheader
762*2d0896c1SWhitney Tsang                         // - skip them.
763*2d0896c1SWhitney Tsang                         ++FI;
764*2d0896c1SWhitney Tsang                         BasicBlock *Header = &*(++FI);
765*2d0896c1SWhitney Tsang                         assert(Header->getName() == "for.body");
766*2d0896c1SWhitney Tsang                         Loop *L = LI.getLoopFor(Header);
767*2d0896c1SWhitney Tsang                         EXPECT_NE(L, nullptr);
768*2d0896c1SWhitney Tsang 
769*2d0896c1SWhitney Tsang                         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
770*2d0896c1SWhitney Tsang                         EXPECT_NE(Bounds, None);
771*2d0896c1SWhitney Tsang                         ConstantInt *InitialIVValue =
772*2d0896c1SWhitney Tsang                             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
773*2d0896c1SWhitney Tsang                         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
774*2d0896c1SWhitney Tsang                         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
775*2d0896c1SWhitney Tsang                         EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
776*2d0896c1SWhitney Tsang                         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
777*2d0896c1SWhitney Tsang                         EXPECT_EQ(Bounds->getCanonicalPredicate(),
778*2d0896c1SWhitney Tsang                                   ICmpInst::BAD_ICMP_PREDICATE);
779*2d0896c1SWhitney Tsang                         EXPECT_EQ(Bounds->getDirection(),
780*2d0896c1SWhitney Tsang                                   Loop::LoopBounds::Direction::Unknown);
781*2d0896c1SWhitney Tsang                         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
782*2d0896c1SWhitney Tsang                       });
783*2d0896c1SWhitney Tsang }
784*2d0896c1SWhitney Tsang 
785*2d0896c1SWhitney Tsang TEST(LoopInfoTest, ZextIndVar) {
786*2d0896c1SWhitney Tsang   const char *ModuleStr =
787*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
788*2d0896c1SWhitney Tsang       "entry:\n"
789*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
790*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
791*2d0896c1SWhitney Tsang       "for.preheader:\n"
792*2d0896c1SWhitney Tsang       "  br label %for.body\n"
793*2d0896c1SWhitney Tsang       "for.body:\n"
794*2d0896c1SWhitney Tsang       "  %indvars.iv = phi i64 [ 0, %for.preheader ], [ %indvars.iv.next, %for.body ]\n"
795*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
796*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
797*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
798*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
799*2d0896c1SWhitney Tsang       "  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
800*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
801*2d0896c1SWhitney Tsang       "  %wide.trip.count = zext i32 %ub to i64\n"
802*2d0896c1SWhitney Tsang       "  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n"
803*2d0896c1SWhitney Tsang       "  br i1 %exitcond, label %for.body, label %for.exit\n"
804*2d0896c1SWhitney Tsang       "for.exit:\n"
805*2d0896c1SWhitney Tsang       "  br label %for.end\n"
806*2d0896c1SWhitney Tsang       "for.end:\n"
807*2d0896c1SWhitney Tsang       "  ret void\n"
808*2d0896c1SWhitney Tsang       "}\n";
809*2d0896c1SWhitney Tsang 
810*2d0896c1SWhitney Tsang   // Parse the module.
811*2d0896c1SWhitney Tsang   LLVMContext Context;
812*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
813*2d0896c1SWhitney Tsang 
814*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
815*2d0896c1SWhitney Tsang       *M, "foo",
816*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
817*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
818*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
819*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
820*2d0896c1SWhitney Tsang         ++FI;
821*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
822*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
823*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
824*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
825*2d0896c1SWhitney Tsang 
826*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
827*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
828*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
829*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
830*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
831*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "indvars.iv.next");
832*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
833*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
834*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
835*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "wide.trip.count");
836*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_NE);
837*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
838*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
839*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "indvars.iv");
840*2d0896c1SWhitney Tsang       });
841*2d0896c1SWhitney Tsang }
842*2d0896c1SWhitney Tsang 
843*2d0896c1SWhitney Tsang TEST(LoopInfoTest, UnguardedLoop) {
844*2d0896c1SWhitney Tsang   const char *ModuleStr =
845*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
846*2d0896c1SWhitney Tsang       "entry:\n"
847*2d0896c1SWhitney Tsang       "  br label %for.body\n"
848*2d0896c1SWhitney Tsang       "for.body:\n"
849*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]\n"
850*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
851*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
852*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
853*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
854*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
855*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
856*2d0896c1SWhitney Tsang       "for.exit:\n"
857*2d0896c1SWhitney Tsang       "  br label %for.end\n"
858*2d0896c1SWhitney Tsang       "for.end:\n"
859*2d0896c1SWhitney Tsang       "  ret void\n"
860*2d0896c1SWhitney Tsang       "}\n";
861*2d0896c1SWhitney Tsang 
862*2d0896c1SWhitney Tsang   // Parse the module.
863*2d0896c1SWhitney Tsang   LLVMContext Context;
864*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
865*2d0896c1SWhitney Tsang 
866*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
867*2d0896c1SWhitney Tsang       *M, "foo",
868*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
869*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
870*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
871*2d0896c1SWhitney Tsang         // First basic block is entry - skip it.
872*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
873*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
874*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
875*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
876*2d0896c1SWhitney Tsang 
877*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
878*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
879*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
880*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
881*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
882*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
883*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
884*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
885*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
886*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
887*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
888*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
889*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
890*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
891*2d0896c1SWhitney Tsang       });
892*2d0896c1SWhitney Tsang }
893*2d0896c1SWhitney Tsang 
894*2d0896c1SWhitney Tsang TEST(LoopInfoTest, UnguardedLoopWithControlFlow) {
895*2d0896c1SWhitney Tsang   const char *ModuleStr =
896*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub, i1 %cond) {\n"
897*2d0896c1SWhitney Tsang       "entry:\n"
898*2d0896c1SWhitney Tsang       "  br i1 %cond, label %for.preheader, label %for.end\n"
899*2d0896c1SWhitney Tsang       "for.preheader:\n"
900*2d0896c1SWhitney Tsang       "  br label %for.body\n"
901*2d0896c1SWhitney Tsang       "for.body:\n"
902*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
903*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
904*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
905*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
906*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
907*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
908*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
909*2d0896c1SWhitney Tsang       "for.exit:\n"
910*2d0896c1SWhitney Tsang       "  br label %for.end\n"
911*2d0896c1SWhitney Tsang       "for.end:\n"
912*2d0896c1SWhitney Tsang       "  ret void\n"
913*2d0896c1SWhitney Tsang       "}\n";
914*2d0896c1SWhitney Tsang 
915*2d0896c1SWhitney Tsang   // Parse the module.
916*2d0896c1SWhitney Tsang   LLVMContext Context;
917*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
918*2d0896c1SWhitney Tsang 
919*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
920*2d0896c1SWhitney Tsang       *M, "foo",
921*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
922*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
923*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
924*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
925*2d0896c1SWhitney Tsang         ++FI;
926*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
927*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
928*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
929*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
930*2d0896c1SWhitney Tsang 
931*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
932*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
933*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
934*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
935*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
936*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
937*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
938*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
939*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
940*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
941*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
942*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
943*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
944*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
945*2d0896c1SWhitney Tsang       });
946*2d0896c1SWhitney Tsang }
947*2d0896c1SWhitney Tsang 
948*2d0896c1SWhitney Tsang TEST(LoopInfoTest, LoopNest) {
949*2d0896c1SWhitney Tsang   const char *ModuleStr =
950*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
951*2d0896c1SWhitney Tsang       "entry:\n"
952*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
953*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.outer.preheader, label %for.end\n"
954*2d0896c1SWhitney Tsang       "for.outer.preheader:\n"
955*2d0896c1SWhitney Tsang       "  br label %for.outer\n"
956*2d0896c1SWhitney Tsang       "for.outer:\n"
957*2d0896c1SWhitney Tsang       "  %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]\n"
958*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch\n"
959*2d0896c1SWhitney Tsang       "for.inner.preheader:\n"
960*2d0896c1SWhitney Tsang       "  br label %for.inner\n"
961*2d0896c1SWhitney Tsang       "for.inner:\n"
962*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]\n"
963*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
964*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
965*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
966*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
967*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
968*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.inner, label %for.inner.exit\n"
969*2d0896c1SWhitney Tsang       "for.inner.exit:\n"
970*2d0896c1SWhitney Tsang       "  br label %for.outer.latch\n"
971*2d0896c1SWhitney Tsang       "for.outer.latch:\n"
972*2d0896c1SWhitney Tsang       "  %inc.outer = add nsw i32 %j, 1\n"
973*2d0896c1SWhitney Tsang       "  %cmp.outer = icmp slt i32 %inc.outer, %ub\n"
974*2d0896c1SWhitney Tsang       "  br i1 %cmp.outer, label %for.outer, label %for.outer.exit\n"
975*2d0896c1SWhitney Tsang       "for.outer.exit:\n"
976*2d0896c1SWhitney Tsang       "  br label %for.end\n"
977*2d0896c1SWhitney Tsang       "for.end:\n"
978*2d0896c1SWhitney Tsang       "  ret void\n"
979*2d0896c1SWhitney Tsang       "}\n";
980*2d0896c1SWhitney Tsang 
981*2d0896c1SWhitney Tsang   // Parse the module.
982*2d0896c1SWhitney Tsang   LLVMContext Context;
983*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
984*2d0896c1SWhitney Tsang 
985*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
986*2d0896c1SWhitney Tsang       *M, "foo",
987*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
988*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
989*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
990*2d0896c1SWhitney Tsang         // First two basic block are entry and for.outer.preheader - skip them.
991*2d0896c1SWhitney Tsang         ++FI;
992*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
993*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.outer");
994*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
995*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
996*2d0896c1SWhitney Tsang 
997*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
998*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
999*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
1000*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
1001*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
1002*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc.outer");
1003*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
1004*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
1005*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
1006*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
1007*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
1008*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
1009*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
1010*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "j");
1011*2d0896c1SWhitney Tsang 
1012*2d0896c1SWhitney Tsang         // Next two basic blocks are for.outer and for.inner.preheader - skip
1013*2d0896c1SWhitney Tsang         // them.
1014*2d0896c1SWhitney Tsang         ++FI;
1015*2d0896c1SWhitney Tsang         Header = &*(++FI);
1016*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.inner");
1017*2d0896c1SWhitney Tsang         L = LI.getLoopFor(Header);
1018*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
1019*2d0896c1SWhitney Tsang 
1020*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> InnerBounds = L->getBounds(SE);
1021*2d0896c1SWhitney Tsang         EXPECT_NE(InnerBounds, None);
1022*2d0896c1SWhitney Tsang         InitialIVValue =
1023*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&InnerBounds->getInitialIVValue());
1024*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
1025*2d0896c1SWhitney Tsang         EXPECT_EQ(InnerBounds->getStepInst().getName(), "inc");
1026*2d0896c1SWhitney Tsang         StepValue = dyn_cast_or_null<ConstantInt>(InnerBounds->getStepValue());
1027*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
1028*2d0896c1SWhitney Tsang         EXPECT_EQ(InnerBounds->getFinalIVValue().getName(), "ub");
1029*2d0896c1SWhitney Tsang         EXPECT_EQ(InnerBounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
1030*2d0896c1SWhitney Tsang         EXPECT_EQ(InnerBounds->getDirection(),
1031*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
1032*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
1033*2d0896c1SWhitney Tsang       });
1034*2d0896c1SWhitney Tsang }
1035*2d0896c1SWhitney Tsang 
1036*2d0896c1SWhitney Tsang TEST(LoopInfoTest, AuxiliaryIV) {
1037*2d0896c1SWhitney Tsang   const char *ModuleStr =
1038*2d0896c1SWhitney Tsang       "define void @foo(i32* %A, i32 %ub) {\n"
1039*2d0896c1SWhitney Tsang       "entry:\n"
1040*2d0896c1SWhitney Tsang       "  %guardcmp = icmp slt i32 0, %ub\n"
1041*2d0896c1SWhitney Tsang       "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
1042*2d0896c1SWhitney Tsang       "for.preheader:\n"
1043*2d0896c1SWhitney Tsang       "  br label %for.body\n"
1044*2d0896c1SWhitney Tsang       "for.body:\n"
1045*2d0896c1SWhitney Tsang       "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
1046*2d0896c1SWhitney Tsang       "  %aux = phi i32 [ 0, %for.preheader ], [ %auxinc, %for.body ]\n"
1047*2d0896c1SWhitney Tsang       "  %loopvariant = phi i32 [ 0, %for.preheader ], [ %loopvariantinc, %for.body ]\n"
1048*2d0896c1SWhitney Tsang       "  %usedoutside = phi i32 [ 0, %for.preheader ], [ %usedoutsideinc, %for.body ]\n"
1049*2d0896c1SWhitney Tsang       "  %mulopcode = phi i32 [ 0, %for.preheader ], [ %mulopcodeinc, %for.body ]\n"
1050*2d0896c1SWhitney Tsang       "  %idxprom = sext i32 %i to i64\n"
1051*2d0896c1SWhitney Tsang       "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
1052*2d0896c1SWhitney Tsang       "  store i32 %i, i32* %arrayidx, align 4\n"
1053*2d0896c1SWhitney Tsang       "  %mulopcodeinc = mul nsw i32 %mulopcode, 5\n"
1054*2d0896c1SWhitney Tsang       "  %usedoutsideinc = add nsw i32 %usedoutside, 5\n"
1055*2d0896c1SWhitney Tsang       "  %loopvariantinc = add nsw i32 %loopvariant, %i\n"
1056*2d0896c1SWhitney Tsang       "  %auxinc = add nsw i32 %aux, 5\n"
1057*2d0896c1SWhitney Tsang       "  %inc = add nsw i32 %i, 1\n"
1058*2d0896c1SWhitney Tsang       "  %cmp = icmp slt i32 %inc, %ub\n"
1059*2d0896c1SWhitney Tsang       "  br i1 %cmp, label %for.body, label %for.exit\n"
1060*2d0896c1SWhitney Tsang       "for.exit:\n"
1061*2d0896c1SWhitney Tsang       "  %lcssa = phi i32 [ %usedoutside, %for.body ]\n"
1062*2d0896c1SWhitney Tsang       "  br label %for.end\n"
1063*2d0896c1SWhitney Tsang       "for.end:\n"
1064*2d0896c1SWhitney Tsang       "  ret void\n"
1065*2d0896c1SWhitney Tsang       "}\n";
1066*2d0896c1SWhitney Tsang 
1067*2d0896c1SWhitney Tsang   // Parse the module.
1068*2d0896c1SWhitney Tsang   LLVMContext Context;
1069*2d0896c1SWhitney Tsang   std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
1070*2d0896c1SWhitney Tsang 
1071*2d0896c1SWhitney Tsang   runWithLoopInfoPlus(
1072*2d0896c1SWhitney Tsang       *M, "foo",
1073*2d0896c1SWhitney Tsang       [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
1074*2d0896c1SWhitney Tsang           PostDominatorTree &PDT) {
1075*2d0896c1SWhitney Tsang         Function::iterator FI = F.begin();
1076*2d0896c1SWhitney Tsang         // First two basic block are entry and for.preheader - skip them.
1077*2d0896c1SWhitney Tsang         ++FI;
1078*2d0896c1SWhitney Tsang         BasicBlock *Header = &*(++FI);
1079*2d0896c1SWhitney Tsang         assert(Header->getName() == "for.body");
1080*2d0896c1SWhitney Tsang         Loop *L = LI.getLoopFor(Header);
1081*2d0896c1SWhitney Tsang         EXPECT_NE(L, nullptr);
1082*2d0896c1SWhitney Tsang 
1083*2d0896c1SWhitney Tsang         Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
1084*2d0896c1SWhitney Tsang         EXPECT_NE(Bounds, None);
1085*2d0896c1SWhitney Tsang         ConstantInt *InitialIVValue =
1086*2d0896c1SWhitney Tsang             dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
1087*2d0896c1SWhitney Tsang         EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
1088*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
1089*2d0896c1SWhitney Tsang         ConstantInt *StepValue =
1090*2d0896c1SWhitney Tsang             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
1091*2d0896c1SWhitney Tsang         EXPECT_TRUE(StepValue && StepValue->isOne());
1092*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
1093*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
1094*2d0896c1SWhitney Tsang         EXPECT_EQ(Bounds->getDirection(),
1095*2d0896c1SWhitney Tsang                   Loop::LoopBounds::Direction::Increasing);
1096*2d0896c1SWhitney Tsang         EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
1097*2d0896c1SWhitney Tsang         BasicBlock::iterator II = Header->begin();
1098*2d0896c1SWhitney Tsang         PHINode &Instruction_i = cast<PHINode>(*(II));
1099*2d0896c1SWhitney Tsang         EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_i, SE));
1100*2d0896c1SWhitney Tsang         PHINode &Instruction_aux = cast<PHINode>(*(++II));
1101*2d0896c1SWhitney Tsang         EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_aux, SE));
1102*2d0896c1SWhitney Tsang         PHINode &Instruction_loopvariant = cast<PHINode>(*(++II));
1103*2d0896c1SWhitney Tsang         EXPECT_FALSE(
1104*2d0896c1SWhitney Tsang             L->isAuxiliaryInductionVariable(Instruction_loopvariant, SE));
1105*2d0896c1SWhitney Tsang         PHINode &Instruction_usedoutside = cast<PHINode>(*(++II));
1106*2d0896c1SWhitney Tsang         EXPECT_FALSE(
1107*2d0896c1SWhitney Tsang             L->isAuxiliaryInductionVariable(Instruction_usedoutside, SE));
1108*2d0896c1SWhitney Tsang         PHINode &Instruction_mulopcode = cast<PHINode>(*(++II));
1109*2d0896c1SWhitney Tsang         EXPECT_FALSE(
1110*2d0896c1SWhitney Tsang             L->isAuxiliaryInductionVariable(Instruction_mulopcode, SE));
1111*2d0896c1SWhitney Tsang       });
1112*2d0896c1SWhitney Tsang }
1113