• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "unit_test.h"
17 #include "optimizer/analysis/bounds_analysis.h"
18 #include "optimizer/optimizations/cleanup.h"
19 #include "optimizer/optimizations/peepholes.h"
20 #include "utils/arena_containers.h"
21 
22 namespace ark::compiler {
23 class BoundsAnalysisTest : public CommonTest {
24 public:
BoundsAnalysisTest()25     BoundsAnalysisTest() : graph_(CreateGraphStartEndBlocks()) {}
26 
GetGraph()27     Graph *GetGraph()
28     {
29         return graph_;
30     }
31 
32     // ll, lr, rl, rr - test bounds
33     // rll, rlr, rrl, rrr - result bounds
CCTest(ConditionCode cc,BoundsRange l,BoundsRange r,BoundsRange rl,BoundsRange rr)34     void CCTest(ConditionCode cc, BoundsRange l, BoundsRange r, BoundsRange rl, BoundsRange rr)
35     {
36         auto [nrl, nrr] = BoundsRange::TryNarrowBoundsByCC(cc, {l, r});
37         ASSERT_EQ(nrl.GetLeft(), rl.GetLeft());
38         ASSERT_EQ(nrl.GetRight(), rl.GetRight());
39         ASSERT_EQ(nrr.GetLeft(), rr.GetLeft());
40         ASSERT_EQ(nrr.GetRight(), rr.GetRight());
41     }
42 
43     using BR = BoundsRange;
44 
45     void TypeFittingBuildGraph();
46 
47 private:
48     Graph *graph_ {nullptr};
49 };
50 // NOLINTBEGIN(readability-magic-numbers)
TEST_F(BoundsAnalysisTest,NegTest)51 TEST_F(BoundsAnalysisTest, NegTest)
52 {
53     BoundsRange r1 = BoundsRange(-1L, 5U);
54     BoundsRange res1 = r1.Neg();
55     EXPECT_EQ(res1.GetLeft(), -5L);
56     EXPECT_EQ(res1.GetRight(), 1U);
57 
58     BoundsRange r2 = BoundsRange(1U, 5U);
59     BoundsRange res2 = r2.Neg();
60     EXPECT_EQ(res2.GetLeft(), -5L);
61     EXPECT_EQ(res2.GetRight(), -1L);
62 
63     BoundsRange r3 = BoundsRange(-5L, -1L);
64     BoundsRange res3 = r3.Neg();
65     EXPECT_EQ(res3.GetLeft(), 1U);
66     EXPECT_EQ(res3.GetRight(), 5U);
67 }
68 
TEST_F(BoundsAnalysisTest,AbsTest)69 TEST_F(BoundsAnalysisTest, AbsTest)
70 {
71     BoundsRange r1 = BoundsRange(1U, 5U);
72     BoundsRange res1 = r1.Abs();
73     EXPECT_EQ(res1.GetLeft(), 1U);
74     EXPECT_EQ(res1.GetRight(), 5U);
75 
76     BoundsRange r2 = BoundsRange(-5L, -1L);
77     BoundsRange res2 = r2.Abs();
78     EXPECT_EQ(res2.GetLeft(), 1U);
79     EXPECT_EQ(res2.GetRight(), 5U);
80 
81     BoundsRange r3 = BoundsRange(-1L, 5U);
82     BoundsRange res3 = r3.Abs();
83     EXPECT_EQ(res3.GetLeft(), 0U);
84     EXPECT_EQ(res3.GetRight(), 5U);
85 
86     BoundsRange r4 = BoundsRange(-10L, 5U);
87     BoundsRange res4 = r4.Abs();
88     EXPECT_EQ(res4.GetLeft(), 0U);
89     EXPECT_EQ(res4.GetRight(), 10U);
90 }
91 
TEST_F(BoundsAnalysisTest,MulTest)92 TEST_F(BoundsAnalysisTest, MulTest)
93 {
94     BoundsRange r1 = BoundsRange(-7L, 5U);
95     BoundsRange r2 = BoundsRange(9U, 13U);
96     BoundsRange r3 = BoundsRange(2U, 5U);
97     BoundsRange r4 = BoundsRange(-4L, -1L);
98     BoundsRange r5 = BoundsRange(-5L, -2L);
99     BoundsRange r6 = BoundsRange(1U, 4U);
100 
101     // All posible variations for GetLeft and GetRight
102     BoundsRange res = r1.Mul(r1);
103     EXPECT_EQ(res.GetLeft(), -7L * 5L);    // min = ll * rr
104     EXPECT_EQ(res.GetRight(), -7L * -7L);  // max = ll * rl
105 
106     res = r2.Mul(r2);
107     EXPECT_EQ(res.GetLeft(), 9U * 9U);     // min = ll * rl
108     EXPECT_EQ(res.GetRight(), 13U * 13U);  // max = lr * rr
109 
110     res = r3.Mul(r4);
111     EXPECT_EQ(res.GetLeft(), 5L * -4L);   // min = lr * rl
112     EXPECT_EQ(res.GetRight(), 2L * -1L);  // max = ll * rr
113 
114     res = r4.Mul(r5);
115     EXPECT_EQ(res.GetLeft(), -1L * -2L);   // min = lr * rr
116     EXPECT_EQ(res.GetRight(), -4L * -5L);  // max = ll * rl
117 
118     res = r5.Mul(r6);
119     EXPECT_EQ(res.GetLeft(), -5L * 4L);   // min = ll * rr
120     EXPECT_EQ(res.GetRight(), -2L * 1L);  // max = lr * rl
121 }
122 
TEST_F(BoundsAnalysisTest,DivTest)123 TEST_F(BoundsAnalysisTest, DivTest)
124 {
125     auto l1 = BoundsRange(-7L, 5U);
126     auto l2 = BoundsRange(5U, 7U);
127     auto l3 = BoundsRange(-7L, -5L);
128     auto r1 = BoundsRange(2U);
129     auto r2 = BoundsRange(-2L);
130     BoundsRange res;
131 
132     res = l1.Div(r1);
133     EXPECT_EQ(res.GetLeft(), -3L);
134     EXPECT_EQ(res.GetRight(), 2U);
135     res = l1.Div(r2);
136     EXPECT_EQ(res.GetLeft(), -2L);
137     EXPECT_EQ(res.GetRight(), 3U);
138 
139     res = l2.Div(r1);
140     EXPECT_EQ(res.GetLeft(), 2U);
141     EXPECT_EQ(res.GetRight(), 3U);
142     res = l2.Div(r2);
143     EXPECT_EQ(res.GetLeft(), -3L);
144     EXPECT_EQ(res.GetRight(), -2L);
145 
146     res = l3.Div(r1);
147     EXPECT_EQ(res.GetLeft(), -3L);
148     EXPECT_EQ(res.GetRight(), -2L);
149     res = l3.Div(r2);
150     EXPECT_EQ(res.GetLeft(), 2U);
151     EXPECT_EQ(res.GetRight(), 3U);
152 }
153 
TEST_F(BoundsAnalysisTest,OverflowTest)154 TEST_F(BoundsAnalysisTest, OverflowTest)
155 {
156     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(INT64_MAX, INT64_MAX), std::nullopt);
157     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(INT64_MAX, 1U), std::nullopt);
158     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(1U, INT64_MAX), std::nullopt);
159     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(INT64_MIN, INT64_MIN), std::nullopt);
160     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(INT64_MIN, -1L), std::nullopt);
161     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(-1L, INT64_MIN), std::nullopt);
162 
163     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(0U, INT64_MAX), 0U);
164     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MAX, 0U), 0U);
165     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(0U, INT64_MIN), 0U);
166     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MIN, 0U), 0U);
167 
168     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MAX, INT64_MAX), std::nullopt);
169     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MAX, 2U), std::nullopt);
170     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MIN, INT64_MIN), std::nullopt);
171     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MIN, -2L), std::nullopt);
172     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MAX, INT64_MIN), std::nullopt);
173     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MAX, -2L), std::nullopt);
174     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MIN, INT64_MAX), std::nullopt);
175     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(INT64_MIN, 2U), std::nullopt);
176 
177     ASSERT_EQ(BoundsRange::DivWithOverflowCheck(INT64_MIN, -1L), std::nullopt);
178 
179     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(UINT64_MAX, UINT64_MAX), std::nullopt);
180     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(UINT64_MAX, 1U), std::nullopt);
181     ASSERT_EQ(BoundsRange::AddWithOverflowCheck(1U, UINT64_MAX), std::nullopt);
182     ASSERT_NE(BoundsRange::AddWithOverflowCheck(UINT64_MAX / 2U, UINT64_MAX / 2U), std::nullopt);
183     ASSERT_NE(BoundsRange::AddWithOverflowCheck(UINT64_MAX - 1U, 1U), std::nullopt);
184     ASSERT_NE(BoundsRange::AddWithOverflowCheck(1U, UINT64_MAX - 1U), std::nullopt);
185 
186     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(0U, UINT64_MAX), 0U);
187     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(UINT64_MAX, 0U), 0U);
188 
189     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(UINT64_MAX, UINT64_MAX), std::nullopt);
190     ASSERT_EQ(BoundsRange::MulWithOverflowCheck(UINT64_MAX / 2U + 1, 2U), std::nullopt);
191     ASSERT_NE(BoundsRange::MulWithOverflowCheck(UINT64_MAX / 2U, 2U), std::nullopt);
192 }
193 
TEST_F(BoundsAnalysisTest,BoundsNarrowing1)194 TEST_F(BoundsAnalysisTest, BoundsNarrowing1)
195 {
196     // case 1
197     CCTest(ConditionCode::CC_GT, BR(10U, 50U), BR(20U, 60U), BR(21U, 50U), BR(20U, 49U));
198     CCTest(ConditionCode::CC_A, BR(10U, 50U), BR(20U, 60U), BR(21U, 50U), BR(20U, 49U));
199     CCTest(ConditionCode::CC_GE, BR(10U, 50U), BR(20U, 60U), BR(20U, 50U), BR(20U, 50U));
200     CCTest(ConditionCode::CC_AE, BR(10U, 50U), BR(20U, 60U), BR(20U, 50U), BR(20U, 50U));
201     CCTest(ConditionCode::CC_LT, BR(10U, 50U), BR(20U, 60U), BR(10U, 50U), BR(20U, 60U));
202     CCTest(ConditionCode::CC_B, BR(10U, 50U), BR(20U, 60U), BR(10U, 50U), BR(20U, 60U));
203     CCTest(ConditionCode::CC_LE, BR(10U, 50U), BR(20U, 60U), BR(10U, 50U), BR(20U, 60U));
204     CCTest(ConditionCode::CC_BE, BR(10U, 50U), BR(20U, 60U), BR(10U, 50U), BR(20U, 60U));
205     CCTest(ConditionCode::CC_EQ, BR(10U, 50U), BR(20U, 60U), BR(20U, 50U), BR(20U, 50U));
206     CCTest(ConditionCode::CC_NE, BR(10U, 50U), BR(20U, 60U), BR(10U, 50U), BR(20U, 60U));
207 
208     // case 2
209     CCTest(ConditionCode::CC_GT, BR(10U, 20U), BR(50U, 60U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
210     CCTest(ConditionCode::CC_A, BR(10U, 20U), BR(50U, 60U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
211     CCTest(ConditionCode::CC_GE, BR(10U, 20U), BR(50U, 60U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
212     CCTest(ConditionCode::CC_AE, BR(10U, 20U), BR(50U, 60U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
213     CCTest(ConditionCode::CC_LT, BR(10U, 20U), BR(50U, 60U), BR(10U, 20U), BR(50U, 60U));
214     CCTest(ConditionCode::CC_B, BR(10U, 20U), BR(50U, 60U), BR(10U, 20U), BR(50U, 60U));
215     CCTest(ConditionCode::CC_LE, BR(10U, 20U), BR(50U, 60U), BR(10U, 20U), BR(50U, 60U));
216     CCTest(ConditionCode::CC_BE, BR(10U, 20U), BR(50U, 60U), BR(10U, 20U), BR(50U, 60U));
217     CCTest(ConditionCode::CC_EQ, BR(10U, 20U), BR(50U, 60U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
218     CCTest(ConditionCode::CC_NE, BR(10U, 20U), BR(50U, 60U), BR(10U, 20U), BR(50U, 60U));
219 
220     // case 3
221     CCTest(ConditionCode::CC_GT, BR(10U, 60U), BR(20U, 50U), BR(21U, 60U), BR(20U, 50U));
222     CCTest(ConditionCode::CC_A, BR(10U, 60U), BR(20U, 50U), BR(21U, 60U), BR(20U, 50U));
223     CCTest(ConditionCode::CC_GE, BR(10U, 60U), BR(20U, 50U), BR(20U, 60U), BR(20U, 50U));
224     CCTest(ConditionCode::CC_AE, BR(10U, 60U), BR(20U, 50U), BR(20U, 60U), BR(20U, 50U));
225     CCTest(ConditionCode::CC_LT, BR(10U, 60U), BR(20U, 50U), BR(10U, 49U), BR(20U, 50U));
226     CCTest(ConditionCode::CC_B, BR(10U, 60U), BR(20U, 50U), BR(10U, 49U), BR(20U, 50U));
227     CCTest(ConditionCode::CC_LE, BR(10U, 60U), BR(20U, 50U), BR(10U, 50U), BR(20U, 50U));
228     CCTest(ConditionCode::CC_BE, BR(10U, 60U), BR(20U, 50U), BR(10U, 50U), BR(20U, 50U));
229     CCTest(ConditionCode::CC_EQ, BR(10U, 60U), BR(20U, 50U), BR(20U, 50U), BR(20U, 50U));
230     CCTest(ConditionCode::CC_NE, BR(10U, 60U), BR(20U, 50U), BR(10U, 60U), BR(20U, 50U));
231 }
232 
TEST_F(BoundsAnalysisTest,BoundsNarrowing2)233 TEST_F(BoundsAnalysisTest, BoundsNarrowing2)
234 {
235     // case 4
236     CCTest(ConditionCode::CC_GT, BR(20U, 60U), BR(10U, 50U), BR(20U, 60U), BR(10U, 50U));
237     CCTest(ConditionCode::CC_A, BR(20U, 60U), BR(10U, 50U), BR(20U, 60U), BR(10U, 50U));
238     CCTest(ConditionCode::CC_GE, BR(20U, 60U), BR(10U, 50U), BR(20U, 60U), BR(10U, 50U));
239     CCTest(ConditionCode::CC_AE, BR(20U, 60U), BR(10U, 50U), BR(20U, 60U), BR(10U, 50U));
240     CCTest(ConditionCode::CC_LT, BR(20U, 60U), BR(10U, 50U), BR(20U, 49U), BR(21U, 50U));
241     CCTest(ConditionCode::CC_B, BR(20U, 60U), BR(10U, 50U), BR(20U, 49U), BR(21U, 50U));
242     CCTest(ConditionCode::CC_LE, BR(20U, 60U), BR(10U, 50U), BR(20U, 50U), BR(20U, 50U));
243     CCTest(ConditionCode::CC_BE, BR(20U, 60U), BR(10U, 50U), BR(20U, 50U), BR(20U, 50U));
244     CCTest(ConditionCode::CC_EQ, BR(20U, 60U), BR(10U, 50U), BR(20U, 50U), BR(20U, 50U));
245     CCTest(ConditionCode::CC_NE, BR(20U, 60U), BR(10U, 50U), BR(20U, 60U), BR(10U, 50U));
246 
247     // case 5
248     CCTest(ConditionCode::CC_GT, BR(50U, 60U), BR(10U, 20U), BR(50U, 60U), BR(10U, 20U));
249     CCTest(ConditionCode::CC_A, BR(50U, 60U), BR(10U, 20U), BR(50U, 60U), BR(10U, 20U));
250     CCTest(ConditionCode::CC_GE, BR(50U, 60U), BR(10U, 20U), BR(50U, 60U), BR(10U, 20U));
251     CCTest(ConditionCode::CC_AE, BR(50U, 60U), BR(10U, 20U), BR(50U, 60U), BR(10U, 20U));
252     CCTest(ConditionCode::CC_LT, BR(50U, 60U), BR(10U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
253     CCTest(ConditionCode::CC_B, BR(50U, 60U), BR(10U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
254     CCTest(ConditionCode::CC_LE, BR(50U, 60U), BR(10U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
255     CCTest(ConditionCode::CC_BE, BR(50U, 60U), BR(10U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
256     CCTest(ConditionCode::CC_EQ, BR(50U, 60U), BR(10U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
257     CCTest(ConditionCode::CC_NE, BR(50U, 60U), BR(10U, 20U), BR(50U, 60U), BR(10U, 20U));
258 
259     // case 6
260     CCTest(ConditionCode::CC_GT, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(10U, 49U));
261     CCTest(ConditionCode::CC_A, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(10U, 49U));
262     CCTest(ConditionCode::CC_GE, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(10U, 50U));
263     CCTest(ConditionCode::CC_AE, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(10U, 50U));
264     CCTest(ConditionCode::CC_LT, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(21U, 60U));
265     CCTest(ConditionCode::CC_B, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(21U, 60U));
266     CCTest(ConditionCode::CC_LE, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(20U, 60U));
267     CCTest(ConditionCode::CC_BE, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(20U, 60U));
268     CCTest(ConditionCode::CC_EQ, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(20U, 50U));
269     CCTest(ConditionCode::CC_NE, BR(20U, 50U), BR(10U, 60U), BR(20U, 50U), BR(10U, 60U));
270 }
271 
TEST_F(BoundsAnalysisTest,IntervalCollisions)272 TEST_F(BoundsAnalysisTest, IntervalCollisions)
273 {
274     // Bounds collision
275     CCTest(ConditionCode::CC_GT, BR(-10L, -5L), BR(-5L, 0U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
276     CCTest(ConditionCode::CC_LT, BR(-5L, 0U), BR(-10L, -5L), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
277     // Single value interval collision
278     CCTest(ConditionCode::CC_GT, BR(0U, 20U), BR(20U, 20U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
279     CCTest(ConditionCode::CC_LT, BR(0U, 20U), BR(0U, 0U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
280     CCTest(ConditionCode::CC_GT, BR(16U, 16U), BR(16U, 32U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
281     CCTest(ConditionCode::CC_LT, BR(32U, 32U), BR(16U, 32U), BR(INT64_MIN, INT64_MAX), BR(INT64_MIN, INT64_MAX));
282 }
283 
TEST_F(BoundsAnalysisTest,UnionTest)284 TEST_F(BoundsAnalysisTest, UnionTest)
285 {
286     ArenaVector<BoundsRange> ranges(GetGraph()->GetAllocator()->Adapter());
287     ranges.emplace_back(BoundsRange(-10L, 100U));
288     ranges.emplace_back(BoundsRange(-20L, 15U));
289     auto range = BoundsRange::Union(ranges);
290     ASSERT_EQ(range.GetLeft(), -20L);
291     ASSERT_EQ(range.GetRight(), 100U);
292     ranges.clear();
293 
294     ranges.emplace_back(BoundsRange(INT64_MIN, -10L));
295     ranges.emplace_back(BoundsRange(10U, INT64_MAX));
296     range = BoundsRange::Union(ranges);
297     ASSERT_EQ(range.GetLeft(), INT64_MIN);
298     ASSERT_EQ(range.GetRight(), INT64_MAX);
299 }
300 
TypeFittingBuildGraph()301 void BoundsAnalysisTest::TypeFittingBuildGraph()
302 {
303     GRAPH(GetGraph())
304     {
305         PARAMETER(0U, 0U).u16();
306         PARAMETER(1U, 1U).s64();
307         PARAMETER(2U, 2U).u32();
308         CONSTANT(3U, 0x23U).s64();
309         CONSTANT(4U, 0x30U).s64();
310         BASIC_BLOCK(2U, 3U, 4U)
311         {
312             // v0 -- ANYTHING
313             // v1 -- ANYTHING
314             // v2 -- ANYTHING
315             INST(5U, Opcode::Compare).b().CC(CC_GT).Inputs(1U, 3U);
316             INST(6U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(5U);
317         }
318         BASIC_BLOCK(4U, 3U, 5U)
319         {
320             // v0 -- ANYTHING
321             // v1 <= 0x23
322             // v2 -- ANYTHING
323             INST(8U, Opcode::Compare).b().CC(CC_GT).Inputs(2U, 4U);
324             INST(9U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(8U);
325         }
326         BASIC_BLOCK(5U, -1L)
327         {
328             // v0 -- ANYTHING
329             // v1 <= 0x23
330             // v2 <= 0x30
331             INST(11U, Opcode::Return).u16().Inputs(0U);
332         }
333         BASIC_BLOCK(3U, -1L)
334         {
335             // v0 -- ANYTHING
336             // v1 -- ANYTHING
337             // v2 -- ANYTHING
338             INST(14U, Opcode::ReturnI).u16().Imm(0x23U);
339         }
340     }
341 }
342 
TEST_F(BoundsAnalysisTest,TypeFitting)343 TEST_F(BoundsAnalysisTest, TypeFitting)
344 {
345     TypeFittingBuildGraph();
346     auto rinfo = GetGraph()->GetBoundsRangeInfo();
347     BoundsRange range;
348 
349     // BB2
350     range = rinfo->FindBoundsRange(&BB(2U), &INS(0U));
351     EXPECT_EQ(range.GetLeft(), 0U);
352     EXPECT_EQ(range.GetRight(), UINT16_MAX);
353 
354     range = rinfo->FindBoundsRange(&BB(2U), &INS(1U));
355     EXPECT_EQ(range.GetLeft(), INT64_MIN);
356     EXPECT_EQ(range.GetRight(), INT64_MAX);
357 
358     range = rinfo->FindBoundsRange(&BB(2U), &INS(2U));
359     EXPECT_EQ(range.GetLeft(), 0U);
360     EXPECT_EQ(range.GetRight(), UINT32_MAX);
361 
362     // BB4
363     range = rinfo->FindBoundsRange(&BB(2U), &INS(0U));
364     EXPECT_EQ(range.GetLeft(), 0U);
365     EXPECT_EQ(range.GetRight(), UINT16_MAX);
366 
367     range = rinfo->FindBoundsRange(&BB(4U), &INS(1U));
368     EXPECT_EQ(range.GetLeft(), INT64_MIN);
369     EXPECT_EQ(range.GetRight(), 0x23U);
370 
371     range = rinfo->FindBoundsRange(&BB(2U), &INS(2U));
372     EXPECT_EQ(range.GetLeft(), 0U);
373     EXPECT_EQ(range.GetRight(), UINT32_MAX);
374 
375     // BB5
376     range = rinfo->FindBoundsRange(&BB(2U), &INS(0U));
377     EXPECT_EQ(range.GetLeft(), 0U);
378     EXPECT_EQ(range.GetRight(), UINT16_MAX);
379 
380     range = rinfo->FindBoundsRange(&BB(4U), &INS(1U));
381     EXPECT_EQ(range.GetLeft(), INT64_MIN);
382     EXPECT_EQ(range.GetRight(), 0x23U);
383 
384     range = rinfo->FindBoundsRange(&BB(5U), &INS(2U));
385     EXPECT_EQ(range.GetLeft(), 0U);
386     EXPECT_EQ(range.GetRight(), 0x30U);
387 
388     // BB3
389     range = rinfo->FindBoundsRange(&BB(2U), &INS(0U));
390     EXPECT_EQ(range.GetLeft(), 0U);
391     EXPECT_EQ(range.GetRight(), UINT16_MAX);
392 
393     range = rinfo->FindBoundsRange(&BB(2U), &INS(1U));
394     EXPECT_EQ(range.GetLeft(), INT64_MIN);
395     EXPECT_EQ(range.GetRight(), INT64_MAX);
396 
397     range = rinfo->FindBoundsRange(&BB(2U), &INS(2U));
398     EXPECT_EQ(range.GetLeft(), 0U);
399     EXPECT_EQ(range.GetRight(), UINT32_MAX);
400 }
401 
TEST_F(BoundsAnalysisTest,NullCompare)402 TEST_F(BoundsAnalysisTest, NullCompare)
403 {
404     GRAPH(GetGraph())
405     {
406         PARAMETER(0U, 0U).ref();
407         CONSTANT(3U, nullptr);
408         BASIC_BLOCK(2U, 3U, 4U)
409         {
410             INST(4U, Opcode::Compare).b().CC(CC_NE).Inputs(3U, 0U);
411             INST(6U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(4U);
412         }
413         BASIC_BLOCK(3U, -1L)
414         {
415             INST(7U, Opcode::SaveState).Inputs(0U, 4U).SrcVregs({2U, 3U});
416             INST(8U, Opcode::NullCheck).ref().Inputs(0U, 7U);
417             INST(9U, Opcode::LoadObject).s64().Inputs(8U).TypeId(243U);
418             INST(10U, Opcode::Return).s64().Inputs(9U);
419         }
420         BASIC_BLOCK(4U, -1L)
421         {
422             INST(13U, Opcode::ReturnI).s64().Imm(0x14U);
423         }
424     }
425     auto rinfo = GetGraph()->GetBoundsRangeInfo();
426     EXPECT_EQ(rinfo->FindBoundsRange(&BB(2U), &INS(0U)).GetLeft(), 0U);
427     EXPECT_EQ(rinfo->FindBoundsRange(&BB(2U), &INS(0U)).GetRight(), BoundsRange::GetMax(INS(0U).GetType()));
428 
429     EXPECT_NE(rinfo->FindBoundsRange(&BB(3U), &INS(0U)).GetLeft(), 0U);
430     EXPECT_EQ(rinfo->FindBoundsRange(&BB(3U), &INS(0U)).GetRight(), BoundsRange::GetMax(INS(0U).GetType()));
431 
432     EXPECT_EQ(rinfo->FindBoundsRange(&BB(4U), &INS(0U)).GetLeft(), 0U);
433     EXPECT_EQ(rinfo->FindBoundsRange(&BB(4U), &INS(0U)).GetRight(), 0U);
434 }
435 
TEST_F(BoundsAnalysisTest,InitMoreThenTest)436 TEST_F(BoundsAnalysisTest, InitMoreThenTest)
437 {
438     // For (int i = 10, i < 0, i++) {}
439     // this loop is counable, but init > test value.
440     GRAPH(GetGraph())
441     {
442         CONSTANT(0U, 10U);
443         CONSTANT(1U, 1U);
444         CONSTANT(2U, 0U);
445         BASIC_BLOCK(2U, 3U, 5U)
446         {
447             INST(5U, Opcode::Compare).SrcType(DataType::INT32).CC(CC_LT).b().Inputs(0U, 2U);
448             INST(6U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(5U);
449         }
450         BASIC_BLOCK(3U, 3U, 5U)
451         {
452             INST(4U, Opcode::Phi).s32().Inputs(0U, 10U);
453 
454             INST(10U, Opcode::Add).s32().Inputs(4U, 1U);
455             INST(13U, Opcode::Compare).CC(CC_LT).b().Inputs(10U, 2U);
456             INST(14U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(13U);
457         }
458         BASIC_BLOCK(5U, 1U)
459         {
460             INST(12U, Opcode::ReturnVoid).v0id();
461         }
462     }
463     auto rinfo = GetGraph()->GetBoundsRangeInfo();
464     auto range = rinfo->FindBoundsRange(&BB(3U), &INS(4U));
465     EXPECT_EQ(range.GetLeft(), INT32_MIN);
466     EXPECT_EQ(range.GetRight(), INT32_MAX);
467 }
468 
TEST_F(BoundsAnalysisTest,ModTest)469 TEST_F(BoundsAnalysisTest, ModTest)
470 {
471     auto res = BoundsRange(0U, 10U).Mod(BoundsRange(0U, 2U));
472     EXPECT_EQ(res.GetLeft(), 0U);
473     EXPECT_EQ(res.GetRight(), 1U);
474 
475     res = BoundsRange(0U, 10U).Mod(BoundsRange(0U));
476     EXPECT_EQ(res.GetLeft(), INT64_MIN);
477     EXPECT_EQ(res.GetRight(), INT64_MAX);
478 
479     // It's correct situation, when right value is 0, and left value isn't 0.
480     res = BoundsRange(-179L, -179L).Mod(BoundsRange(INT64_MIN, 0U));
481     EXPECT_EQ(res.GetLeft(), -179L);
482     EXPECT_EQ(res.GetRight(), 0U);
483 
484     res = BoundsRange(5U, 10U).Mod(BoundsRange(-3L));
485     EXPECT_EQ(res.GetLeft(), 0U);
486     EXPECT_EQ(res.GetRight(), 2U);
487 
488     res = BoundsRange(-10L, -5L).Mod(BoundsRange(-3L));
489     EXPECT_EQ(res.GetLeft(), -2L);
490     EXPECT_EQ(res.GetRight(), 0U);
491 
492     res = BoundsRange(-10L, 10U).Mod(BoundsRange(3U));
493     EXPECT_EQ(res.GetLeft(), -2L);
494     EXPECT_EQ(res.GetRight(), 2U);
495 
496     res = BoundsRange(-3L, 3U).Mod(BoundsRange(-10L, 10U));
497     EXPECT_EQ(res.GetLeft(), -3L);
498     EXPECT_EQ(res.GetRight(), 3U);
499 }
500 
TEST_F(BoundsAnalysisTest,LoopWithBigStep)501 TEST_F(BoundsAnalysisTest, LoopWithBigStep)
502 {
503     // For (int i = 0, i < 5, i += 10) {}
504     // this loop is countable, and init + step > test value.
505     GRAPH(GetGraph())
506     {
507         CONSTANT(0U, 0U);
508         CONSTANT(1U, 5U);
509         CONSTANT(2U, 10U);
510         BASIC_BLOCK(2U, 3U, 5U)
511         {
512             INST(5U, Opcode::Compare).SrcType(DataType::INT32).CC(CC_LT).b().Inputs(0U, 1U);
513             INST(6U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(5U);
514         }
515         BASIC_BLOCK(3U, 3U, 5U)
516         {
517             INST(4U, Opcode::Phi).s32().Inputs(0U, 10U);
518 
519             INST(10U, Opcode::Add).s32().Inputs(4U, 2U);
520             INST(13U, Opcode::Compare).CC(CC_LT).b().Inputs(10U, 1U);
521             INST(14U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(13U);
522         }
523         BASIC_BLOCK(5U, 1U)
524         {
525             INST(12U, Opcode::ReturnVoid).v0id();
526         }
527     }
528     auto rinfo = GetGraph()->GetBoundsRangeInfo();
529     auto range = rinfo->FindBoundsRange(&BB(3U), &INS(4U));
530     EXPECT_EQ(range.GetLeft(), 0U);
531     EXPECT_EQ(range.GetRight(), 4U);
532 }
533 
TEST_F(BoundsAnalysisTest,LoopWithBigStep2)534 TEST_F(BoundsAnalysisTest, LoopWithBigStep2)
535 {
536     // For (int i = 1, i < 6, i += 2) {}
537     GRAPH(GetGraph())
538     {
539         CONSTANT(0U, 0U);
540         CONSTANT(1U, 6U);
541         CONSTANT(2U, 2U);
542         BASIC_BLOCK(2U, 3U, 5U)
543         {
544             INST(5U, Opcode::Compare).SrcType(DataType::INT32).CC(CC_LT).b().Inputs(0U, 1U);
545             INST(6U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(5U);
546         }
547         BASIC_BLOCK(3U, 3U, 5U)
548         {
549             INST(4U, Opcode::Phi).s32().Inputs(0U, 10U);
550 
551             INST(10U, Opcode::Add).s32().Inputs(4U, 2U);
552             INST(13U, Opcode::Compare).CC(CC_LT).b().Inputs(10U, 1U);
553             INST(14U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(13U);
554         }
555         BASIC_BLOCK(5U, 1U)
556         {
557             INST(12U, Opcode::ReturnVoid).v0id();
558         }
559     }
560     auto rinfo = GetGraph()->GetBoundsRangeInfo();
561     auto range = rinfo->FindBoundsRange(&BB(3U), &INS(4U));
562     EXPECT_EQ(range.GetLeft(), 0U);
563     // Check that right bound is (upper - 1)
564     EXPECT_EQ(range.GetRight(), 5U);
565 }
566 
TEST_F(BoundsAnalysisTest,ShrTest)567 TEST_F(BoundsAnalysisTest, ShrTest)
568 {
569     auto r1 = BoundsRange(2U);
570     auto max = BoundsRange();
571     auto r2 = BoundsRange(4U, 8U);
572     auto neg = BoundsRange(-1L);
573 
574     EXPECT_EQ(r2.Shr(r2), max);
575     EXPECT_EQ(r2.Shr(neg), max);
576     EXPECT_EQ(r2.Shr(r1), BoundsRange(1U, 2U));
577 
578     EXPECT_EQ(BoundsRange(-1L).Shr(BoundsRange(4U)), BoundsRange(0x0FFFFFFFFFFFFFFFU));
579     EXPECT_EQ(BoundsRange(-1L, 16U).Shr(BoundsRange(4U)), BoundsRange(0U, 0x0FFFFFFFFFFFFFFFU));
580     EXPECT_EQ(BoundsRange(9U, 15U).Shr(BoundsRange(2U)), BoundsRange(2U, 3U));
581     EXPECT_EQ(BoundsRange(-15L, -9L).Shr(BoundsRange(2U)), BoundsRange(0x3FFFFFFFFFFFFFFCU, 0x3FFFFFFFFFFFFFFDU));
582     EXPECT_EQ(BoundsRange(-100L, 100U).Shr(BoundsRange(4U)), BoundsRange(0U, 0x0FFFFFFFFFFFFFFFU));
583 }
584 
TEST_F(BoundsAnalysisTest,AShrTest)585 TEST_F(BoundsAnalysisTest, AShrTest)
586 {
587     auto r1 = BoundsRange(2U);
588     auto max = BoundsRange();
589     auto r2 = BoundsRange(4U, 8U);
590     auto neg = BoundsRange(-1L);
591 
592     EXPECT_EQ(r2.AShr(r2), max);
593     EXPECT_EQ(r2.AShr(neg), max);
594     EXPECT_EQ(r2.AShr(r1), BoundsRange(1U, 2U));
595 
596     EXPECT_EQ(BoundsRange(-1L).AShr(BoundsRange(4U)), BoundsRange(-1L));
597     EXPECT_EQ(BoundsRange(-1L, 16U).AShr(BoundsRange(4U)), BoundsRange(-1L, 1U));
598 }
599 
TEST_F(BoundsAnalysisTest,ShlTest)600 TEST_F(BoundsAnalysisTest, ShlTest)
601 {
602     auto max = BoundsRange();
603     auto r = BoundsRange(4U, 8U);
604     auto neg = BoundsRange(-1L);
605 
606     EXPECT_EQ(r.Shl(r), max);
607     EXPECT_EQ(r.Shl(neg), max);
608 
609     EXPECT_EQ(r.Shl(BoundsRange(2U)), BoundsRange(16U, 32U));
610     EXPECT_EQ(BoundsRange(-1L).Shl(BoundsRange(4U)), BoundsRange(0xFFFFFFFFFFFFFFF0U));
611     EXPECT_EQ(BoundsRange(-1L, 16U).Shl(BoundsRange(4U)), BoundsRange(0xFFFFFFFFFFFFFFF0U, 256U));
612     EXPECT_EQ(BoundsRange(16U, 0x0FFFFFFFFFFFFFFFU).Shl(BoundsRange(4U)), BoundsRange());
613 }
614 
TEST_F(BoundsAnalysisTest,SignedDivTest)615 TEST_F(BoundsAnalysisTest, SignedDivTest)
616 {
617     GRAPH(GetGraph())
618     {
619         PARAMETER(0U, 0U).s32();
620         CONSTANT(1U, 4U);
621         BASIC_BLOCK(2U, -1L)
622         {
623             INST(2U, Opcode::Div).s32().Inputs(0U, 1U);
624             INST(3U, Opcode::Return).s32().Inputs(2U);
625         }
626     }
627 
628     ASSERT_FALSE(GetGraph()->RunPass<Peepholes>());
629     ASSERT_FALSE(GetGraph()->RunPass<Cleanup>());
630 
631     auto bb = &BB(2U);
632 
633     auto graph = CreateEmptyGraph();
634     GRAPH(graph)
635     {
636         PARAMETER(0U, 0U).s32();
637         CONSTANT(1U, 4U);
638         BASIC_BLOCK(2U, -1L)
639         {
640             INST(2U, Opcode::Div).s32().Inputs(0U, 1U);
641             INST(3U, Opcode::Return).s32().Inputs(2U);
642         }
643     }
644     ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
645 
646     auto bri = GetGraph()->GetBoundsRangeInfo();
647     auto range = bri->FindBoundsRange(bb, bb->GetLastInst()->GetInput(0U).GetInst());
648     ASSERT_EQ(range, BoundsRange(INT32_MIN / 4L, INT32_MAX / 4L));
649 }
650 
TEST_F(BoundsAnalysisTest,AndTest)651 TEST_F(BoundsAnalysisTest, AndTest)
652 {
653     EXPECT_EQ(BoundsRange().And(BoundsRange(1U, 2U)), BoundsRange());
654     EXPECT_EQ(BoundsRange().And(BoundsRange(0x2U)), BoundsRange(0U, 0x2U));
655     EXPECT_EQ(BoundsRange().And(BoundsRange(0x3U)), BoundsRange(0U, 0x3U));
656     EXPECT_EQ(BoundsRange().And(BoundsRange(-1L)), BoundsRange());
657     EXPECT_EQ(BoundsRange().And(BoundsRange(0x8000000000000000U)), BoundsRange());
658 }
659 
TEST_F(BoundsAnalysisTest,UINT64_INPUTS)660 TEST_F(BoundsAnalysisTest, UINT64_INPUTS)
661 {
662     GRAPH(GetGraph())
663     {
664         PARAMETER(0U, 0U).ref();
665         BASIC_BLOCK(2U, -1L)
666         {
667             INST(1U, Opcode::LoadObject).u64().Inputs(0U);
668             INST(2U, Opcode::LoadObject).u64().Inputs(0U);
669             INST(3U, Opcode::Add).i64().Inputs(1U, 2U);
670             INST(4U, Opcode::Return).u64().Inputs(3U);
671         }
672     }
673     auto bri = GetGraph()->GetBoundsRangeInfo();
674     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(1U)), BoundsRange(0U, INT64_MAX));
675     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(3U)), BoundsRange(INT64_MIN, INT64_MAX));
676     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(4U)), BoundsRange(0U, INT64_MAX));
677 }
678 
TEST_F(BoundsAnalysisTest,Different_types)679 TEST_F(BoundsAnalysisTest, Different_types)
680 {
681     GRAPH(GetGraph())
682     {
683         PARAMETER(0U, 0U).u64();
684         CONSTANT(1U, 2U);
685         BASIC_BLOCK(2U, -1L)
686         {
687             INST(2U, Opcode::Div).i64().Inputs(0U, 1U);
688             INST(3U, Opcode::Return).i64().Inputs(2U);
689         }
690     }
691     auto bri = GetGraph()->GetBoundsRangeInfo();
692     ASSERT_EQ(bri->FindBoundsRange(&BB(0U), &INS(0U)), BoundsRange(0U, INT64_MAX));
693     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(2U)), BoundsRange(INT64_MIN, INT64_MAX));
694     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(3U)), BoundsRange(INT64_MIN, INT64_MAX));
695 }
696 
697 /*
698  *              [0]
699  *               |
700  *               v
701  *      /------>[2]------\
702  *      |        |       |
703  *      |       [3]      |
704  *      |       / \      |
705  *      |      v   v     v
706  *      |     [4] [5]   [7]
707  *      |       \ /      |
708  *      \-------[6]    [exit]
709  *
710  */
TEST_F(BoundsAnalysisTest,LoopWithBranch)711 TEST_F(BoundsAnalysisTest, LoopWithBranch)
712 {
713     GRAPH(GetGraph())
714     {
715         PARAMETER(0U, 0U).b();
716         CONSTANT(1U, 0U);
717         CONSTANT(15U, 1U);
718         CONSTANT(2U, 2U);
719         CONSTANT(25U, 10U);
720         BASIC_BLOCK(2U, 3U, 7U)
721         {
722             INST(3U, Opcode::Phi).Inputs(1U, 9U).u64();   // index
723             INST(35U, Opcode::Phi).Inputs(1U, 8U).u64();  // init
724             INST(4U, Opcode::Compare).CC(CC_LT).b().Inputs(3U, 25U);
725             INST(45U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(4U);
726         }
727         BASIC_BLOCK(3U, 4U, 5U)
728         {
729             INST(5U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(0U);
730         }
731         BASIC_BLOCK(4U, 6U)
732         {
733             INST(6U, Opcode::Add).Inputs(35U, 2U).u64();
734         }
735         BASIC_BLOCK(5U, 6U)
736         {
737             INST(7U, Opcode::Add).Inputs(35U, 15U).u64();
738         }
739         BASIC_BLOCK(6U, 2U)
740         {
741             INST(8U, Opcode::Phi).Inputs(6U, 7U).u64();  // update
742             INST(9U, Opcode::Add).Inputs(3U, 15U).u64();
743         }
744         BASIC_BLOCK(7U, -1L)
745         {
746             INST(10U, Opcode::Return).Inputs(35U).u64();
747         }
748     }
749     auto bri = GetGraph()->GetBoundsRangeInfo();
750     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(3U)), BoundsRange(0U, 9U));
751     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(35U)), BoundsRange(0U, 20U));
752     ASSERT_EQ(bri->FindBoundsRange(&BB(6U), &INS(8U)), BoundsRange(10U, 20U));
753 }
754 
TEST_F(BoundsAnalysisTest,NegativePhi)755 TEST_F(BoundsAnalysisTest, NegativePhi)
756 {
757     GRAPH(GetGraph())
758     {
759         CONSTANT(2U, 100U);
760         CONSTANT(3U, 5U);
761         CONSTANT(4U, 0U);
762         CONSTANT(5U, 4U);
763         CONSTANT(16U, 1U);
764         BASIC_BLOCK(3U, 4U, 2U)
765         {
766             INST(21U, Opcode::Compare).CC(CC_GE).b().Inputs(4U, 3U).SrcType(DataType::INT32);
767             INST(22U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(21U);
768         }
769         BASIC_BLOCK(2U, 4U, 2U)
770         {
771             INST(9U, Opcode::Phi).Inputs(4U, 15U).i32();
772             INST(10U, Opcode::Phi).Inputs(5U, 14U).i32();
773             INST(14U, Opcode::Sub).Inputs(2U, 10U).i32();
774             INST(15U, Opcode::Add).Inputs(9U, 16U).i32();
775             INST(12U, Opcode::Compare).CC(CC_GE).b().Inputs(15U, 3U);
776             INST(13U, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0U).Inputs(12U);
777         }
778         BASIC_BLOCK(4U, -1L)
779         {
780             INST(20U, Opcode::Return).Inputs(16U).i32();
781         }
782     }
783     auto bri = GetGraph()->GetBoundsRangeInfo();
784     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(9U)), BoundsRange(0U, 4U));
785     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(10U)), BoundsRange(INT32_MIN, INT32_MAX));
786     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(14U)), BoundsRange(INT32_MIN, INT32_MAX));
787     ASSERT_EQ(bri->FindBoundsRange(&BB(2U), &INS(15U)), BoundsRange(1U, 5U));
788 }
789 // NOLINTEND(readability-magic-numbers)
790 
791 }  // namespace ark::compiler
792