1 //===- IVDescriptorsTest.cpp - IVDescriptors 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/IVDescriptors.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/Dominators.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
21 /// Build the loop info and scalar evolution for the function and run the Test.
22 static void runWithLoopInfoAndSE(
23 Module
&M
, StringRef FuncName
,
24 function_ref
<void(Function
&F
, LoopInfo
&LI
, ScalarEvolution
&SE
)> Test
) {
25 auto *F
= M
.getFunction(FuncName
);
26 ASSERT_NE(F
, nullptr) << "Could not find " << FuncName
;
28 TargetLibraryInfoImpl TLII
;
29 TargetLibraryInfo
TLI(TLII
);
30 AssumptionCache
AC(*F
);
33 ScalarEvolution
SE(*F
, TLI
, AC
, DT
, LI
);
38 static std::unique_ptr
<Module
> parseIR(LLVMContext
&C
, const char *IR
) {
40 std::unique_ptr
<Module
> Mod
= parseAssemblyString(IR
, Err
, C
);
42 Err
.print("IVDescriptorsTests", errs());
46 // This tests that IVDescriptors can obtain the induction binary operator for
47 // integer induction variables. And hasUnsafeAlgebra() and
48 // getUnsafeAlgebraInst() correctly return the expected behavior, i.e. no unsafe
50 TEST(IVDescriptorsTest
, LoopWithSingleLatch
) {
54 std::unique_ptr
<Module
> M
= parseIR(
56 R
"(define void @foo(i32* %A, i32 %ub) {
60 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
61 %idxprom = sext i32 %i to i64
62 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
63 store i32 %i, i32* %arrayidx, align 4
64 %inc = add nsw i32 %i, 1
65 %cmp = icmp slt i32 %inc, %ub
66 br i1 %cmp, label %for.body, label %for.exit
75 *M
, "foo", [&](Function
&F
, LoopInfo
&LI
, ScalarEvolution
&SE
) {
76 Function::iterator FI
= F
.begin();
77 // First basic block is entry - skip it.
78 BasicBlock
*Header
= &*(++FI
);
79 assert(Header
->getName() == "for.body");
80 Loop
*L
= LI
.getLoopFor(Header
);
81 EXPECT_NE(L
, nullptr);
82 PHINode
*Inst_i
= dyn_cast
<PHINode
>(&Header
->front());
83 assert(Inst_i
->getName() == "i");
84 InductionDescriptor IndDesc
;
86 InductionDescriptor::isInductionPHI(Inst_i
, L
, &SE
, IndDesc
);
87 EXPECT_TRUE(IsInductionPHI
);
88 Instruction
*Inst_inc
= nullptr;
89 BasicBlock::iterator BBI
= Header
->begin();
91 if ((&*BBI
)->getName() == "inc")
95 assert(Inst_inc
->getName() == "inc");
96 EXPECT_EQ(IndDesc
.getInductionBinOp(), Inst_inc
);
97 EXPECT_FALSE(IndDesc
.hasUnsafeAlgebra());
98 EXPECT_EQ(IndDesc
.getUnsafeAlgebraInst(), nullptr);