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