1 //===- UnrollLoopTest.cpp - Unit tests for UnrollLoop ---------------------===// 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/Transforms/Utils/UnrollLoop.h" 10 #include "llvm/Analysis/AssumptionCache.h" 11 #include "llvm/Analysis/LoopInfo.h" 12 #include "llvm/Analysis/ScalarEvolution.h" 13 #include "llvm/Analysis/TargetLibraryInfo.h" 14 #include "llvm/AsmParser/Parser.h" 15 #include "llvm/IR/BasicBlock.h" 16 #include "llvm/IR/Dominators.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/Support/SourceMgr.h" 20 #include "gtest/gtest.h" 21 22 using namespace llvm; 23 24 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) { 25 SMDiagnostic Err; 26 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C); 27 if (!Mod) 28 Err.print("UnrollLoopTests", errs()); 29 return Mod; 30 } 31 32 TEST(LoopUnrollRuntime, Latch) { 33 LLVMContext C; 34 35 std::unique_ptr<Module> M = parseIR( 36 C, 37 R"(define i32 @test(i32* %a, i32* %b, i32* %c, i64 %n) { 38 entry: 39 br label %while.cond 40 41 while.cond: ; preds = %while.body, %entry 42 %i.0 = phi i64 [ 0, %entry ], [ %inc, %while.body ] 43 %cmp = icmp slt i64 %i.0, %n 44 br i1 %cmp, label %while.body, label %while.end 45 46 while.body: ; preds = %while.cond 47 %arrayidx = getelementptr inbounds i32, i32* %b, i64 %i.0 48 %0 = load i32, i32* %arrayidx 49 %arrayidx1 = getelementptr inbounds i32, i32* %c, i64 %i.0 50 %1 = load i32, i32* %arrayidx1 51 %mul = mul nsw i32 %0, %1 52 %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %i.0 53 store i32 %mul, i32* %arrayidx2 54 %inc = add nsw i64 %i.0, 1 55 br label %while.cond 56 57 while.end: ; preds = %while.cond 58 ret i32 0 59 })" 60 ); 61 62 auto *F = M->getFunction("test"); 63 DominatorTree DT(*F); 64 LoopInfo LI(DT); 65 AssumptionCache AC(*F); 66 TargetLibraryInfoImpl TLII; 67 TargetLibraryInfo TLI(TLII); 68 ScalarEvolution SE(*F, TLI, AC, DT, LI); 69 70 Loop *L = *LI.begin(); 71 72 bool PreserveLCSSA = L->isRecursivelyLCSSAForm(DT,LI); 73 74 bool ret = 75 UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI, &SE, &DT, 76 &AC, /*TTI=*/nullptr, PreserveLCSSA, 4, false); 77 EXPECT_FALSE(ret); 78 } 79