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 getExactFPMathInst() correctly return the
48 // expected behavior, i.e. no FMF algebra.
49 TEST(IVDescriptorsTest
, LoopWithSingleLatch
) {
53 std::unique_ptr
<Module
> M
= parseIR(
55 R
"(define void @foo(i32* %A, i32 %ub) {
59 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
60 %idxprom = sext i32 %i to i64
61 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
62 store i32 %i, i32* %arrayidx, align 4
63 %inc = add nsw i32 %i, 1
64 %cmp = icmp slt i32 %inc, %ub
65 br i1 %cmp, label %for.body, label %for.exit
74 *M
, "foo", [&](Function
&F
, LoopInfo
&LI
, ScalarEvolution
&SE
) {
75 Function::iterator FI
= F
.begin();
76 // First basic block is entry - skip it.
77 BasicBlock
*Header
= &*(++FI
);
78 assert(Header
->getName() == "for.body");
79 Loop
*L
= LI
.getLoopFor(Header
);
80 EXPECT_NE(L
, nullptr);
81 PHINode
*Inst_i
= dyn_cast
<PHINode
>(&Header
->front());
82 assert(Inst_i
->getName() == "i");
83 InductionDescriptor IndDesc
;
85 InductionDescriptor::isInductionPHI(Inst_i
, L
, &SE
, IndDesc
);
86 EXPECT_TRUE(IsInductionPHI
);
87 Instruction
*Inst_inc
= nullptr;
88 BasicBlock::iterator BBI
= Header
->begin();
90 if ((&*BBI
)->getName() == "inc")
94 assert(Inst_inc
->getName() == "inc");
95 EXPECT_EQ(IndDesc
.getInductionBinOp(), Inst_inc
);
96 EXPECT_EQ(IndDesc
.getExactFPMathInst(), nullptr);
100 TEST(IVDescriptorsTest
, LoopWithScalableTypes
) {
104 std::unique_ptr
<Module
> M
=
106 R
"(define void @foo(<vscale x 4 x float>* %ptr) {
111 %lsr.iv1 = phi <vscale x 4 x float>* [ %0, %for.body ], [ %ptr, %entry ]
112 %j.0117 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
113 %lsr.iv12 = bitcast <vscale x 4 x float>* %lsr.iv1 to i8*
114 %inc = add nuw nsw i64 %j.0117, 1
115 %uglygep = getelementptr i8, i8* %lsr.iv12, i64 4
116 %0 = bitcast i8* %uglygep to <vscale x 4 x float>*
117 %cmp = icmp ne i64 %inc, 1024
118 br i1 %cmp, label %for.body, label %end
124 runWithLoopInfoAndSE(
125 *M
, "foo", [&](Function
&F
, LoopInfo
&LI
, ScalarEvolution
&SE
) {
126 Function::iterator FI
= F
.begin();
127 // First basic block is entry - skip it.
128 BasicBlock
*Header
= &*(++FI
);
129 assert(Header
->getName() == "for.body");
130 Loop
*L
= LI
.getLoopFor(Header
);
131 EXPECT_NE(L
, nullptr);
132 PHINode
*Inst_iv
= dyn_cast
<PHINode
>(&Header
->front());
133 assert(Inst_iv
->getName() == "lsr.iv1");
134 InductionDescriptor IndDesc
;
135 bool IsInductionPHI
=
136 InductionDescriptor::isInductionPHI(Inst_iv
, L
, &SE
, IndDesc
);
137 EXPECT_FALSE(IsInductionPHI
);
141 // Depending on how SCEV deals with ptrtoint cast, the step of a phi could be
142 // a pointer, and InductionDescriptor used to fail with an assertion.
143 // So just check that it doesn't assert.
144 TEST(IVDescriptorsTest
, LoopWithPtrToInt
) {
148 std::unique_ptr
<Module
> M
= parseIR(Context
, R
"(
149 target datalayout = "e
-m
:e
-p
:32:32-Fi8
-i64
:64-v128
:64:128-a
:0:32-n32
-S64
"
150 target triple = "thumbv6m
-arm
-none
-eabi
"
152 declare void @widget()
153 declare void @wobble(i32)
155 define void @barney(i8* %arg, i8* %arg18, i32 %arg19) {
157 %tmp = ptrtoint i8* %arg to i32
158 %tmp20 = ptrtoint i8* %arg18 to i32
159 %tmp21 = or i32 %tmp20, %tmp
160 %tmp22 = and i32 %tmp21, 3
161 %tmp23 = icmp eq i32 %tmp22, 0
162 br i1 %tmp23, label %bb24, label %bb25
165 tail call void @widget()
169 %tmp26 = sub i32 %tmp, %tmp20
170 %tmp27 = icmp ult i32 %tmp26, %arg19
171 br i1 %tmp27, label %bb28, label %bb34
177 %tmp30 = phi i32 [ %tmp31, %bb29 ], [ %arg19, %bb28 ]
178 tail call void @wobble(i32 %tmp26)
179 %tmp31 = sub i32 %tmp30, %tmp26
180 %tmp32 = icmp ugt i32 %tmp31, %tmp26
181 br i1 %tmp32, label %bb29, label %bb33
190 runWithLoopInfoAndSE(
191 *M
, "barney", [&](Function
&F
, LoopInfo
&LI
, ScalarEvolution
&SE
) {
192 Function::iterator FI
= F
.begin();
193 // First basic block is entry - skip it.
194 BasicBlock
*Header
= &*(++(++(++(++FI
))));
195 assert(Header
->getName() == "bb29");
196 Loop
*L
= LI
.getLoopFor(Header
);
197 EXPECT_NE(L
, nullptr);
198 PHINode
*Inst_i
= dyn_cast
<PHINode
>(&Header
->front());
199 assert(Inst_i
->getName() == "tmp30");
200 InductionDescriptor IndDesc
;
201 bool IsInductionPHI
=
202 InductionDescriptor::isInductionPHI(Inst_i
, L
, &SE
, IndDesc
);
203 EXPECT_TRUE(IsInductionPHI
);