1ca02360fSXin Tong //===- LoopInfoTest.cpp - LoopInfo unit tests -----------------------------===// 2ca02360fSXin Tong // 3ca02360fSXin Tong // The LLVM Compiler Infrastructure 4ca02360fSXin Tong // 5ca02360fSXin Tong // This file is distributed under the University of Illinois Open Source 6ca02360fSXin Tong // License. See LICENSE.TXT for details. 7ca02360fSXin Tong // 8ca02360fSXin Tong //===----------------------------------------------------------------------===// 9ca02360fSXin Tong 10ca02360fSXin Tong #include "llvm/Analysis/LoopInfo.h" 11ca02360fSXin Tong #include "llvm/AsmParser/Parser.h" 12ca02360fSXin Tong #include "llvm/IR/Dominators.h" 13ca02360fSXin Tong #include "llvm/Support/SourceMgr.h" 14ca02360fSXin Tong #include "gtest/gtest.h" 15ca02360fSXin Tong 16ca02360fSXin Tong using namespace llvm; 17ca02360fSXin Tong 1843c1a264SXin Tong /// Build the loop info for the function and run the Test. 1943c1a264SXin Tong static void 2043c1a264SXin Tong runWithLoopInfo(Module &M, StringRef FuncName, 2143c1a264SXin Tong function_ref<void(Function &F, LoopInfo &LI)> Test) { 2243c1a264SXin Tong auto *F = M.getFunction(FuncName); 2343c1a264SXin Tong ASSERT_NE(F, nullptr) << "Could not find " << FuncName; 2443c1a264SXin Tong // Compute the dominator tree and the loop info for the function. 2543c1a264SXin Tong DominatorTree DT(*F); 2643c1a264SXin Tong LoopInfo LI(DT); 2743c1a264SXin Tong Test(*F, LI); 2843c1a264SXin Tong } 2943c1a264SXin Tong 30ca02360fSXin Tong static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context, 31ca02360fSXin Tong const char *ModuleStr) { 32ca02360fSXin Tong SMDiagnostic Err; 33ca02360fSXin Tong return parseAssemblyString(ModuleStr, Err, Context); 34ca02360fSXin Tong } 35ca02360fSXin Tong 36ca02360fSXin Tong // This tests that for a loop with a single latch, we get the loop id from 37ca02360fSXin Tong // its only latch, even in case the loop may not be in a simplified form. 38ca02360fSXin Tong TEST(LoopInfoTest, LoopWithSingleLatch) { 39ca02360fSXin Tong const char *ModuleStr = 40ca02360fSXin Tong "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n" 41ca02360fSXin Tong "define void @foo(i32 %n) {\n" 42ca02360fSXin Tong "entry:\n" 43ca02360fSXin Tong " br i1 undef, label %for.cond, label %for.end\n" 44ca02360fSXin Tong "for.cond:\n" 45ca02360fSXin Tong " %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n" 46ca02360fSXin Tong " %cmp = icmp slt i32 %i.0, %n\n" 47ca02360fSXin Tong " br i1 %cmp, label %for.inc, label %for.end\n" 48ca02360fSXin Tong "for.inc:\n" 49ca02360fSXin Tong " %inc = add nsw i32 %i.0, 1\n" 50ca02360fSXin Tong " br label %for.cond, !llvm.loop !0\n" 51ca02360fSXin Tong "for.end:\n" 52ca02360fSXin Tong " ret void\n" 53ca02360fSXin Tong "}\n" 54ca02360fSXin Tong "!0 = distinct !{!0, !1}\n" 55ca02360fSXin Tong "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n"; 56ca02360fSXin Tong 57ca02360fSXin Tong // Parse the module. 58ca02360fSXin Tong LLVMContext Context; 59ca02360fSXin Tong std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr); 60ca02360fSXin Tong 6143c1a264SXin Tong runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) { 62ca02360fSXin Tong Function::iterator FI = F.begin(); 6343c1a264SXin Tong // First basic block is entry - skip it. 6443c1a264SXin Tong BasicBlock *Header = &*(++FI); 65ca02360fSXin Tong assert(Header->getName() == "for.cond"); 66ca02360fSXin Tong Loop *L = LI.getLoopFor(Header); 67ca02360fSXin Tong 68ca02360fSXin Tong // This loop is not in simplified form. 69ca02360fSXin Tong EXPECT_FALSE(L->isLoopSimplifyForm()); 70ca02360fSXin Tong 71ca02360fSXin Tong // Analyze the loop metadata id. 72ca02360fSXin Tong bool loopIDFoundAndSet = false; 73ca02360fSXin Tong // Try to get and set the metadata id for the loop. 74ca02360fSXin Tong if (MDNode *D = L->getLoopID()) { 75ca02360fSXin Tong L->setLoopID(D); 76ca02360fSXin Tong loopIDFoundAndSet = true; 77ca02360fSXin Tong } 78ca02360fSXin Tong 79ca02360fSXin Tong // We must have successfully found and set the loop id in the 80ca02360fSXin Tong // only latch the loop has. 81ca02360fSXin Tong EXPECT_TRUE(loopIDFoundAndSet); 8243c1a264SXin Tong }); 83ca02360fSXin Tong } 84f002264dSChandler Carruth 85*a58e9214SJohannes Doerfert // Test loop id handling for a loop with multiple latches. 86*a58e9214SJohannes Doerfert TEST(LoopInfoTest, LoopWithMultipleLatches) { 87*a58e9214SJohannes Doerfert const char *ModuleStr = 88*a58e9214SJohannes Doerfert "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n" 89*a58e9214SJohannes Doerfert "define void @foo(i32 %n) {\n" 90*a58e9214SJohannes Doerfert "entry:\n" 91*a58e9214SJohannes Doerfert " br i1 undef, label %for.cond, label %for.end\n" 92*a58e9214SJohannes Doerfert "for.cond:\n" 93*a58e9214SJohannes Doerfert " %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n" 94*a58e9214SJohannes Doerfert " %inc = add nsw i32 %i.0, 1\n" 95*a58e9214SJohannes Doerfert " %cmp = icmp slt i32 %i.0, %n\n" 96*a58e9214SJohannes Doerfert " br i1 %cmp, label %latch.1, label %for.end\n" 97*a58e9214SJohannes Doerfert "latch.1:\n" 98*a58e9214SJohannes Doerfert " br i1 undef, label %for.cond, label %latch.2, !llvm.loop !0\n" 99*a58e9214SJohannes Doerfert "latch.2:\n" 100*a58e9214SJohannes Doerfert " br label %for.cond, !llvm.loop !0\n" 101*a58e9214SJohannes Doerfert "for.end:\n" 102*a58e9214SJohannes Doerfert " ret void\n" 103*a58e9214SJohannes Doerfert "}\n" 104*a58e9214SJohannes Doerfert "!0 = distinct !{!0, !1}\n" 105*a58e9214SJohannes Doerfert "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n"; 106*a58e9214SJohannes Doerfert 107*a58e9214SJohannes Doerfert // Parse the module. 108*a58e9214SJohannes Doerfert LLVMContext Context; 109*a58e9214SJohannes Doerfert std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr); 110*a58e9214SJohannes Doerfert 111*a58e9214SJohannes Doerfert runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) { 112*a58e9214SJohannes Doerfert Function::iterator FI = F.begin(); 113*a58e9214SJohannes Doerfert F.dump(); 114*a58e9214SJohannes Doerfert // First basic block is entry - skip it. 115*a58e9214SJohannes Doerfert BasicBlock *Header = &*(++FI); 116*a58e9214SJohannes Doerfert assert(Header->getName() == "for.cond"); 117*a58e9214SJohannes Doerfert Loop *L = LI.getLoopFor(Header); 118*a58e9214SJohannes Doerfert EXPECT_NE(L, nullptr); 119*a58e9214SJohannes Doerfert 120*a58e9214SJohannes Doerfert // This loop is not in simplified form. 121*a58e9214SJohannes Doerfert EXPECT_FALSE(L->isLoopSimplifyForm()); 122*a58e9214SJohannes Doerfert 123*a58e9214SJohannes Doerfert // Try to get and set the metadata id for the loop. 124*a58e9214SJohannes Doerfert MDNode *OldLoopID = L->getLoopID(); 125*a58e9214SJohannes Doerfert EXPECT_NE(OldLoopID, nullptr); 126*a58e9214SJohannes Doerfert 127*a58e9214SJohannes Doerfert MDNode *NewLoopID = MDNode::get(Context, {nullptr}); 128*a58e9214SJohannes Doerfert // Set operand 0 to refer to the loop id itself. 129*a58e9214SJohannes Doerfert NewLoopID->replaceOperandWith(0, NewLoopID); 130*a58e9214SJohannes Doerfert 131*a58e9214SJohannes Doerfert L->setLoopID(NewLoopID); 132*a58e9214SJohannes Doerfert EXPECT_EQ(L->getLoopID(), NewLoopID); 133*a58e9214SJohannes Doerfert EXPECT_NE(L->getLoopID(), OldLoopID); 134*a58e9214SJohannes Doerfert 135*a58e9214SJohannes Doerfert L->setLoopID(OldLoopID); 136*a58e9214SJohannes Doerfert EXPECT_EQ(L->getLoopID(), OldLoopID); 137*a58e9214SJohannes Doerfert EXPECT_NE(L->getLoopID(), NewLoopID); 138*a58e9214SJohannes Doerfert }); 139*a58e9214SJohannes Doerfert } 140*a58e9214SJohannes Doerfert 141f002264dSChandler Carruth TEST(LoopInfoTest, PreorderTraversals) { 142f002264dSChandler Carruth const char *ModuleStr = "define void @f() {\n" 143f002264dSChandler Carruth "entry:\n" 144f002264dSChandler Carruth " br label %loop.0\n" 145f002264dSChandler Carruth "loop.0:\n" 146f002264dSChandler Carruth " br i1 undef, label %loop.0.0, label %loop.1\n" 147f002264dSChandler Carruth "loop.0.0:\n" 148f002264dSChandler Carruth " br i1 undef, label %loop.0.0, label %loop.0.1\n" 149f002264dSChandler Carruth "loop.0.1:\n" 150f002264dSChandler Carruth " br i1 undef, label %loop.0.1, label %loop.0.2\n" 151f002264dSChandler Carruth "loop.0.2:\n" 152f002264dSChandler Carruth " br i1 undef, label %loop.0.2, label %loop.0\n" 153f002264dSChandler Carruth "loop.1:\n" 154f002264dSChandler Carruth " br i1 undef, label %loop.1.0, label %end\n" 155f002264dSChandler Carruth "loop.1.0:\n" 156f002264dSChandler Carruth " br i1 undef, label %loop.1.0, label %loop.1.1\n" 157f002264dSChandler Carruth "loop.1.1:\n" 158f002264dSChandler Carruth " br i1 undef, label %loop.1.1, label %loop.1.2\n" 159f002264dSChandler Carruth "loop.1.2:\n" 160f002264dSChandler Carruth " br i1 undef, label %loop.1.2, label %loop.1\n" 161f002264dSChandler Carruth "end:\n" 162f002264dSChandler Carruth " ret void\n" 163f002264dSChandler Carruth "}\n"; 164f002264dSChandler Carruth // Parse the module. 165f002264dSChandler Carruth LLVMContext Context; 166f002264dSChandler Carruth std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr); 167f002264dSChandler Carruth Function &F = *M->begin(); 168f002264dSChandler Carruth 169f002264dSChandler Carruth DominatorTree DT(F); 170f002264dSChandler Carruth LoopInfo LI; 171f002264dSChandler Carruth LI.analyze(DT); 172f002264dSChandler Carruth 173f002264dSChandler Carruth Function::iterator I = F.begin(); 174f002264dSChandler Carruth ASSERT_EQ("entry", I->getName()); 175f002264dSChandler Carruth ++I; 176f002264dSChandler Carruth Loop &L_0 = *LI.getLoopFor(&*I++); 177f002264dSChandler Carruth ASSERT_EQ("loop.0", L_0.getHeader()->getName()); 178f002264dSChandler Carruth Loop &L_0_0 = *LI.getLoopFor(&*I++); 179f002264dSChandler Carruth ASSERT_EQ("loop.0.0", L_0_0.getHeader()->getName()); 180f002264dSChandler Carruth Loop &L_0_1 = *LI.getLoopFor(&*I++); 181f002264dSChandler Carruth ASSERT_EQ("loop.0.1", L_0_1.getHeader()->getName()); 182f002264dSChandler Carruth Loop &L_0_2 = *LI.getLoopFor(&*I++); 183f002264dSChandler Carruth ASSERT_EQ("loop.0.2", L_0_2.getHeader()->getName()); 184f002264dSChandler Carruth Loop &L_1 = *LI.getLoopFor(&*I++); 185f002264dSChandler Carruth ASSERT_EQ("loop.1", L_1.getHeader()->getName()); 186f002264dSChandler Carruth Loop &L_1_0 = *LI.getLoopFor(&*I++); 187f002264dSChandler Carruth ASSERT_EQ("loop.1.0", L_1_0.getHeader()->getName()); 188f002264dSChandler Carruth Loop &L_1_1 = *LI.getLoopFor(&*I++); 189f002264dSChandler Carruth ASSERT_EQ("loop.1.1", L_1_1.getHeader()->getName()); 190f002264dSChandler Carruth Loop &L_1_2 = *LI.getLoopFor(&*I++); 191f002264dSChandler Carruth ASSERT_EQ("loop.1.2", L_1_2.getHeader()->getName()); 192f002264dSChandler Carruth 193f002264dSChandler Carruth auto Preorder = LI.getLoopsInPreorder(); 194f002264dSChandler Carruth ASSERT_EQ(8u, Preorder.size()); 195f002264dSChandler Carruth EXPECT_EQ(&L_0, Preorder[0]); 196f002264dSChandler Carruth EXPECT_EQ(&L_0_0, Preorder[1]); 197f002264dSChandler Carruth EXPECT_EQ(&L_0_1, Preorder[2]); 198f002264dSChandler Carruth EXPECT_EQ(&L_0_2, Preorder[3]); 199f002264dSChandler Carruth EXPECT_EQ(&L_1, Preorder[4]); 200f002264dSChandler Carruth EXPECT_EQ(&L_1_0, Preorder[5]); 201f002264dSChandler Carruth EXPECT_EQ(&L_1_1, Preorder[6]); 202f002264dSChandler Carruth EXPECT_EQ(&L_1_2, Preorder[7]); 203f002264dSChandler Carruth 204f002264dSChandler Carruth auto ReverseSiblingPreorder = LI.getLoopsInReverseSiblingPreorder(); 205f002264dSChandler Carruth ASSERT_EQ(8u, ReverseSiblingPreorder.size()); 206f002264dSChandler Carruth EXPECT_EQ(&L_1, ReverseSiblingPreorder[0]); 207f002264dSChandler Carruth EXPECT_EQ(&L_1_2, ReverseSiblingPreorder[1]); 208f002264dSChandler Carruth EXPECT_EQ(&L_1_1, ReverseSiblingPreorder[2]); 209f002264dSChandler Carruth EXPECT_EQ(&L_1_0, ReverseSiblingPreorder[3]); 210f002264dSChandler Carruth EXPECT_EQ(&L_0, ReverseSiblingPreorder[4]); 211f002264dSChandler Carruth EXPECT_EQ(&L_0_2, ReverseSiblingPreorder[5]); 212f002264dSChandler Carruth EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]); 213f002264dSChandler Carruth EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]); 214f002264dSChandler Carruth } 215