1 //===- LoopInfoTest.cpp - LoopInfo unit tests -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/LoopInfo.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Dominators.h"
12 #include "llvm/Support/SourceMgr.h"
13 #include "gtest/gtest.h"
17 /// Build the loop info for the function and run the Test.
19 runWithLoopInfo(Module
&M
, StringRef FuncName
,
20 function_ref
<void(Function
&F
, LoopInfo
&LI
)> Test
) {
21 auto *F
= M
.getFunction(FuncName
);
22 ASSERT_NE(F
, nullptr) << "Could not find " << FuncName
;
23 // Compute the dominator tree and the loop info for the function.
29 static std::unique_ptr
<Module
> makeLLVMModule(LLVMContext
&Context
,
30 const char *ModuleStr
) {
32 return parseAssemblyString(ModuleStr
, Err
, Context
);
35 // This tests that for a loop with a single latch, we get the loop id from
36 // its only latch, even in case the loop may not be in a simplified form.
37 TEST(LoopInfoTest
, LoopWithSingleLatch
) {
38 const char *ModuleStr
=
39 "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
40 "define void @foo(i32 %n) {\n"
42 " br i1 undef, label %for.cond, label %for.end\n"
44 " %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
45 " %cmp = icmp slt i32 %i.0, %n\n"
46 " br i1 %cmp, label %for.inc, label %for.end\n"
48 " %inc = add nsw i32 %i.0, 1\n"
49 " br label %for.cond, !llvm.loop !0\n"
53 "!0 = distinct !{!0, !1}\n"
54 "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
58 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleStr
);
60 runWithLoopInfo(*M
, "foo", [&](Function
&F
, LoopInfo
&LI
) {
61 Function::iterator FI
= F
.begin();
62 // First basic block is entry - skip it.
63 BasicBlock
*Header
= &*(++FI
);
64 assert(Header
->getName() == "for.cond");
65 Loop
*L
= LI
.getLoopFor(Header
);
67 // This loop is not in simplified form.
68 EXPECT_FALSE(L
->isLoopSimplifyForm());
70 // Analyze the loop metadata id.
71 bool loopIDFoundAndSet
= false;
72 // Try to get and set the metadata id for the loop.
73 if (MDNode
*D
= L
->getLoopID()) {
75 loopIDFoundAndSet
= true;
78 // We must have successfully found and set the loop id in the
79 // only latch the loop has.
80 EXPECT_TRUE(loopIDFoundAndSet
);
84 // Test loop id handling for a loop with multiple latches.
85 TEST(LoopInfoTest
, LoopWithMultipleLatches
) {
86 const char *ModuleStr
=
87 "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
88 "define void @foo(i32 %n) {\n"
90 " br i1 undef, label %for.cond, label %for.end\n"
92 " %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n"
93 " %inc = add nsw i32 %i.0, 1\n"
94 " %cmp = icmp slt i32 %i.0, %n\n"
95 " br i1 %cmp, label %latch.1, label %for.end\n"
97 " br i1 undef, label %for.cond, label %latch.2, !llvm.loop !0\n"
99 " br label %for.cond, !llvm.loop !0\n"
103 "!0 = distinct !{!0, !1}\n"
104 "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
108 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleStr
);
110 runWithLoopInfo(*M
, "foo", [&](Function
&F
, LoopInfo
&LI
) {
111 Function::iterator FI
= F
.begin();
112 // First basic block is entry - skip it.
113 BasicBlock
*Header
= &*(++FI
);
114 assert(Header
->getName() == "for.cond");
115 Loop
*L
= LI
.getLoopFor(Header
);
116 EXPECT_NE(L
, nullptr);
118 // This loop is not in simplified form.
119 EXPECT_FALSE(L
->isLoopSimplifyForm());
121 // Try to get and set the metadata id for the loop.
122 MDNode
*OldLoopID
= L
->getLoopID();
123 EXPECT_NE(OldLoopID
, nullptr);
125 MDNode
*NewLoopID
= MDNode::get(Context
, {nullptr});
126 // Set operand 0 to refer to the loop id itself.
127 NewLoopID
->replaceOperandWith(0, NewLoopID
);
129 L
->setLoopID(NewLoopID
);
130 EXPECT_EQ(L
->getLoopID(), NewLoopID
);
131 EXPECT_NE(L
->getLoopID(), OldLoopID
);
133 L
->setLoopID(OldLoopID
);
134 EXPECT_EQ(L
->getLoopID(), OldLoopID
);
135 EXPECT_NE(L
->getLoopID(), NewLoopID
);
139 TEST(LoopInfoTest
, PreorderTraversals
) {
140 const char *ModuleStr
= "define void @f() {\n"
142 " br label %loop.0\n"
144 " br i1 undef, label %loop.0.0, label %loop.1\n"
146 " br i1 undef, label %loop.0.0, label %loop.0.1\n"
148 " br i1 undef, label %loop.0.1, label %loop.0.2\n"
150 " br i1 undef, label %loop.0.2, label %loop.0\n"
152 " br i1 undef, label %loop.1.0, label %end\n"
154 " br i1 undef, label %loop.1.0, label %loop.1.1\n"
156 " br i1 undef, label %loop.1.1, label %loop.1.2\n"
158 " br i1 undef, label %loop.1.2, label %loop.1\n"
164 std::unique_ptr
<Module
> M
= makeLLVMModule(Context
, ModuleStr
);
165 Function
&F
= *M
->begin();
171 Function::iterator I
= F
.begin();
172 ASSERT_EQ("entry", I
->getName());
174 Loop
&L_0
= *LI
.getLoopFor(&*I
++);
175 ASSERT_EQ("loop.0", L_0
.getHeader()->getName());
176 Loop
&L_0_0
= *LI
.getLoopFor(&*I
++);
177 ASSERT_EQ("loop.0.0", L_0_0
.getHeader()->getName());
178 Loop
&L_0_1
= *LI
.getLoopFor(&*I
++);
179 ASSERT_EQ("loop.0.1", L_0_1
.getHeader()->getName());
180 Loop
&L_0_2
= *LI
.getLoopFor(&*I
++);
181 ASSERT_EQ("loop.0.2", L_0_2
.getHeader()->getName());
182 Loop
&L_1
= *LI
.getLoopFor(&*I
++);
183 ASSERT_EQ("loop.1", L_1
.getHeader()->getName());
184 Loop
&L_1_0
= *LI
.getLoopFor(&*I
++);
185 ASSERT_EQ("loop.1.0", L_1_0
.getHeader()->getName());
186 Loop
&L_1_1
= *LI
.getLoopFor(&*I
++);
187 ASSERT_EQ("loop.1.1", L_1_1
.getHeader()->getName());
188 Loop
&L_1_2
= *LI
.getLoopFor(&*I
++);
189 ASSERT_EQ("loop.1.2", L_1_2
.getHeader()->getName());
191 auto Preorder
= LI
.getLoopsInPreorder();
192 ASSERT_EQ(8u, Preorder
.size());
193 EXPECT_EQ(&L_0
, Preorder
[0]);
194 EXPECT_EQ(&L_0_0
, Preorder
[1]);
195 EXPECT_EQ(&L_0_1
, Preorder
[2]);
196 EXPECT_EQ(&L_0_2
, Preorder
[3]);
197 EXPECT_EQ(&L_1
, Preorder
[4]);
198 EXPECT_EQ(&L_1_0
, Preorder
[5]);
199 EXPECT_EQ(&L_1_1
, Preorder
[6]);
200 EXPECT_EQ(&L_1_2
, Preorder
[7]);
202 auto ReverseSiblingPreorder
= LI
.getLoopsInReverseSiblingPreorder();
203 ASSERT_EQ(8u, ReverseSiblingPreorder
.size());
204 EXPECT_EQ(&L_1
, ReverseSiblingPreorder
[0]);
205 EXPECT_EQ(&L_1_2
, ReverseSiblingPreorder
[1]);
206 EXPECT_EQ(&L_1_1
, ReverseSiblingPreorder
[2]);
207 EXPECT_EQ(&L_1_0
, ReverseSiblingPreorder
[3]);
208 EXPECT_EQ(&L_0
, ReverseSiblingPreorder
[4]);
209 EXPECT_EQ(&L_0_2
, ReverseSiblingPreorder
[5]);
210 EXPECT_EQ(&L_0_1
, ReverseSiblingPreorder
[6]);
211 EXPECT_EQ(&L_0_0
, ReverseSiblingPreorder
[7]);