1 /*
2 * Copyright © 2022 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <gtest/gtest.h>
24 #include "nir.h"
25 #include "nir_builder.h"
26
27 class nir_loop_analyze_test : public ::testing::Test {
28 protected:
29 nir_loop_analyze_test();
30 ~nir_loop_analyze_test();
31
32 nir_builder b;
33 };
34
nir_loop_analyze_test()35 nir_loop_analyze_test::nir_loop_analyze_test()
36 {
37 glsl_type_singleton_init_or_ref();
38
39 static nir_shader_compiler_options options = { };
40
41 options.max_unroll_iterations = 32;
42
43 b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, &options,
44 "loop analyze");
45 }
46
~nir_loop_analyze_test()47 nir_loop_analyze_test::~nir_loop_analyze_test()
48 {
49 ralloc_free(b.shader);
50 glsl_type_singleton_decref();
51 }
52
53 struct loop_builder_param {
54 uint32_t init_value;
55 uint32_t cond_value;
56 uint32_t incr_value;
57 nir_def *(*cond_instr)(nir_builder *,
58 nir_def *,
59 nir_def *);
60 nir_def *(*incr_instr)(nir_builder *,
61 nir_def *,
62 nir_def *);
63 };
64
65 static nir_loop *
loop_builder(nir_builder * b,loop_builder_param p)66 loop_builder(nir_builder *b, loop_builder_param p)
67 {
68 /* Create IR:
69 *
70 * auto i = init_value;
71 * while (true) {
72 * if (cond_instr(i, cond_value))
73 * break;
74 *
75 * i = incr_instr(i, incr_value);
76 * }
77 */
78 nir_def *ssa_0 = nir_imm_int(b, p.init_value);
79 nir_def *ssa_1 = nir_imm_int(b, p.cond_value);
80 nir_def *ssa_2 = nir_imm_int(b, p.incr_value);
81
82 nir_phi_instr *const phi = nir_phi_instr_create(b->shader);
83
84 nir_loop *loop = nir_push_loop(b);
85 {
86 nir_def_init(&phi->instr, &phi->def, ssa_0->num_components,
87 ssa_0->bit_size);
88
89 nir_phi_instr_add_src(phi, ssa_0->parent_instr->block, ssa_0);
90
91 nir_def *ssa_5 = &phi->def;
92 nir_def *ssa_3 = p.cond_instr(b, ssa_5, ssa_1);
93
94 nir_if *nif = nir_push_if(b, ssa_3);
95 {
96 nir_jump_instr *jump = nir_jump_instr_create(b->shader, nir_jump_break);
97 nir_builder_instr_insert(b, &jump->instr);
98 }
99 nir_pop_if(b, nif);
100
101 nir_def *ssa_4 = p.incr_instr(b, ssa_5, ssa_2);
102
103 nir_phi_instr_add_src(phi, ssa_4->parent_instr->block, ssa_4);
104 }
105 nir_pop_loop(b, loop);
106
107 b->cursor = nir_before_block(nir_loop_first_block(loop));
108 nir_builder_instr_insert(b, &phi->instr);
109
110 return loop;
111 }
112
113 struct loop_builder_invert_param {
114 uint32_t init_value;
115 uint32_t incr_value;
116 uint32_t cond_value;
117 nir_def *(*cond_instr)(nir_builder *,
118 nir_def *,
119 nir_def *);
120 nir_def *(*incr_instr)(nir_builder *,
121 nir_def *,
122 nir_def *);
123 };
124
125 /**
126 * Build an "inverted" loop.
127 *
128 * Like \c loop_builder, but the exit condition for the loop is at the bottom
129 * of the loop instead of the top. In compiler literature, the optimization
130 * that moves the exit condition from the top to the bottom is called "loop
131 * inversion," hence the name of this function.
132 */
133 static nir_loop *
loop_builder_invert(nir_builder * b,loop_builder_invert_param p)134 loop_builder_invert(nir_builder *b, loop_builder_invert_param p)
135 {
136 /* Create IR:
137 *
138 * auto i = init_value;
139 * while (true) {
140 * i = incr_instr(i, incr_value);
141 *
142 * if (cond_instr(i, cond_value))
143 * break;
144 * }
145 */
146 nir_def *ssa_0 = nir_imm_int(b, p.init_value);
147 nir_def *ssa_1 = nir_imm_int(b, p.incr_value);
148 nir_def *ssa_2 = nir_imm_int(b, p.cond_value);
149
150 nir_phi_instr *const phi = nir_phi_instr_create(b->shader);
151
152 nir_loop *loop = nir_push_loop(b);
153 {
154 nir_def_init(&phi->instr, &phi->def, ssa_0->num_components,
155 ssa_0->bit_size);
156
157 nir_phi_instr_add_src(phi, ssa_0->parent_instr->block, ssa_0);
158
159 nir_def *ssa_5 = &phi->def;
160
161 nir_def *ssa_3 = p.incr_instr(b, ssa_5, ssa_1);
162
163 nir_def *ssa_4 = p.cond_instr(b, ssa_3, ssa_2);
164
165 nir_if *nif = nir_push_if(b, ssa_4);
166 {
167 nir_jump_instr *jump = nir_jump_instr_create(b->shader, nir_jump_break);
168 nir_builder_instr_insert(b, &jump->instr);
169 }
170 nir_pop_if(b, nif);
171
172 nir_phi_instr_add_src(phi, nir_cursor_current_block(b->cursor), ssa_3);
173 }
174 nir_pop_loop(b, loop);
175
176 b->cursor = nir_before_block(nir_loop_first_block(loop));
177 nir_builder_instr_insert(b, &phi->instr);
178
179 return loop;
180 }
181
TEST_F(nir_loop_analyze_test,one_iteration_fneu)182 TEST_F(nir_loop_analyze_test, one_iteration_fneu)
183 {
184 /* Create IR:
185 *
186 * float i = uintBitsToFloat(0xe7000000);
187 * while (true) {
188 * if (i != uintBitsToFloat(0xe7000000))
189 * break;
190 *
191 * i = i + uintBitsToFloat(0x5b000000);
192 * }
193 *
194 * Going towards smaller magnitude (i.e., adding a small positive value to
195 * a large negative value) requires a smaller delta to make a difference
196 * than going towards a larger magnitude. For this reason, ssa_0 + ssa_1 !=
197 * ssa_0, but ssa_0 - ssa_1 == ssa_0. Math class is tough.
198 */
199 nir_loop *loop =
200 loop_builder(&b, {.init_value = 0xe7000000, .cond_value = 0xe7000000,
201 .incr_value = 0x5b000000,
202 .cond_instr = nir_fneu, .incr_instr = nir_fadd});
203
204 /* At this point, we should have:
205 *
206 * impl main {
207 * block block_0:
208 * // preds:
209 * vec1 32 ssa_0 = load_const (0xe7000000 = -604462909807314587353088.0)
210 * vec1 32 ssa_1 = load_const (0xe7000000 = -604462909807314587353088.0)
211 * vec1 32 ssa_2 = load_const (0x5b000000 = 36028797018963968.0)
212 * // succs: block_1
213 * loop {
214 * block block_1:
215 * // preds: block_0 block_4
216 * vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
217 * vec1 1 ssa_3 = fneu ssa_5, ssa_1
218 * // succs: block_2 block_3
219 * if ssa_3 {
220 * block block_2:
221 * // preds: block_1
222 * break
223 * // succs: block_5
224 * } else {
225 * block block_3:
226 * // preds: block_1
227 * // succs: block_4
228 * }
229 * block block_4:
230 * // preds: block_3
231 * vec1 32 ssa_4 = fadd ssa_5, ssa_2
232 * // succs: block_1
233 * }
234 * block block_5:
235 * // preds: block_2
236 * // succs: block_6
237 * block block_6:
238 * }
239 */
240 nir_validate_shader(b.shader, "input");
241
242 nir_loop_analyze_impl(b.impl, nir_var_all, false);
243
244 ASSERT_NE((void *)0, loop->info);
245 EXPECT_EQ(1, loop->info->max_trip_count);
246 EXPECT_TRUE(loop->info->exact_trip_count_known);
247
248 /* Loop should have an induction variable for ssa_5 and ssa_4. */
249 EXPECT_EQ(2, loop->info->num_induction_vars);
250 ASSERT_NE((void *)0, loop->info->induction_vars);
251
252 /* The def field should not be NULL. The init_src field should point to a
253 * load_const. The update_src field should point to a load_const.
254 */
255 const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
256
257 for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
258 EXPECT_NE((void *)0, ivars[i].def);
259 ASSERT_NE((void *)0, ivars[i].init_src);
260 EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
261 ASSERT_NE((void *)0, ivars[i].update_src);
262 EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
263 }
264 }
265
266 #define COMPARE_REVERSE(comp) \
267 static nir_def * \
268 nir_ ## comp ## _rev(nir_builder *b, nir_def *x, nir_def *y) \
269 { \
270 return nir_ ## comp (b, y, x); \
271 }
272
273 COMPARE_REVERSE(ilt)
274 COMPARE_REVERSE(ige)
275 COMPARE_REVERSE(ult)
276 COMPARE_REVERSE(uge)
277 COMPARE_REVERSE(ishl)
278
279 #define INOT_COMPARE(comp) \
280 static nir_def * \
281 nir_inot_ ## comp (nir_builder *b, nir_def *x, nir_def *y) \
282 { \
283 return nir_inot(b, nir_ ## comp (b, x, y)); \
284 }
285
286 INOT_COMPARE(ilt_rev)
287 INOT_COMPARE(ine)
288 INOT_COMPARE(uge_rev)
289
290 #define CMP_MIN(cmp, min) \
291 static nir_def *nir_##cmp##_##min(nir_builder *b, nir_def *counter, nir_def *limit) \
292 { \
293 nir_def *unk = nir_load_vertex_id(b); \
294 return nir_##cmp(b, counter, nir_##min(b, limit, unk)); \
295 }
296
297 #define CMP_MIN_REV(cmp, min) \
298 static nir_def *nir_##cmp##_##min##_rev(nir_builder *b, nir_def *counter, nir_def *limit) \
299 { \
300 nir_def *unk = nir_load_vertex_id(b); \
301 return nir_##cmp(b, nir_##min(b, limit, unk), counter); \
302 }
303
304 CMP_MIN(ige, imin)
305 CMP_MIN_REV(ige, imin)
306 CMP_MIN(uge, umin)
307 CMP_MIN(ige, fmin)
308 CMP_MIN(uge, imin)
309 CMP_MIN(ilt, imin)
310 CMP_MIN(ilt, imax)
311 CMP_MIN_REV(ilt, imin)
312 INOT_COMPARE(ilt_imin_rev)
313
314 #define KNOWN_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr, count) \
315 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _known_count_ ## count) \
316 { \
317 nir_loop *loop = \
318 loop_builder(&b, {.init_value = _init_value, \
319 .cond_value = _cond_value, \
320 .incr_value = _incr_value, \
321 .cond_instr = nir_ ## cond, \
322 .incr_instr = nir_ ## incr}); \
323 \
324 nir_validate_shader(b.shader, "input"); \
325 \
326 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
327 \
328 ASSERT_NE((void *)0, loop->info); \
329 EXPECT_NE((void *)0, loop->info->limiting_terminator); \
330 EXPECT_EQ(count, loop->info->max_trip_count); \
331 EXPECT_TRUE(loop->info->exact_trip_count_known); \
332 \
333 EXPECT_EQ(2, loop->info->num_induction_vars); \
334 ASSERT_NE((void *)0, loop->info->induction_vars); \
335 \
336 const nir_loop_induction_variable *const ivars = \
337 loop->info->induction_vars; \
338 \
339 for (unsigned i = 0; i < loop->info->num_induction_vars; i++) { \
340 EXPECT_NE((void *)0, ivars[i].def); \
341 ASSERT_NE((void *)0, ivars[i].init_src); \
342 EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src)); \
343 ASSERT_NE((void *)0, ivars[i].update_src); \
344 EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src)); \
345 } \
346 }
347
348 #define INEXACT_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr, count) \
349 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _inexact_count_ ## count) \
350 { \
351 nir_loop *loop = \
352 loop_builder(&b, {.init_value = _init_value, \
353 .cond_value = _cond_value, \
354 .incr_value = _incr_value, \
355 .cond_instr = nir_ ## cond, \
356 .incr_instr = nir_ ## incr}); \
357 \
358 nir_validate_shader(b.shader, "input"); \
359 \
360 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
361 \
362 ASSERT_NE((void *)0, loop->info); \
363 EXPECT_NE((void *)0, loop->info->limiting_terminator); \
364 EXPECT_EQ(count, loop->info->max_trip_count); \
365 EXPECT_FALSE(loop->info->exact_trip_count_known); \
366 \
367 EXPECT_EQ(2, loop->info->num_induction_vars); \
368 ASSERT_NE((void *)0, loop->info->induction_vars); \
369 \
370 const nir_loop_induction_variable *const ivars = \
371 loop->info->induction_vars; \
372 \
373 for (unsigned i = 0; i < loop->info->num_induction_vars; i++) { \
374 EXPECT_NE((void *)0, ivars[i].def); \
375 ASSERT_NE((void *)0, ivars[i].init_src); \
376 EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src)); \
377 ASSERT_NE((void *)0, ivars[i].update_src); \
378 EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src)); \
379 } \
380 }
381
382 #define UNKNOWN_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr) \
383 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _unknown_count) \
384 { \
385 nir_loop *loop = \
386 loop_builder(&b, {.init_value = _init_value, \
387 .cond_value = _cond_value, \
388 .incr_value = _incr_value, \
389 .cond_instr = nir_ ## cond, \
390 .incr_instr = nir_ ## incr}); \
391 \
392 nir_validate_shader(b.shader, "input"); \
393 \
394 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
395 \
396 ASSERT_NE((void *)0, loop->info); \
397 EXPECT_EQ((void *)0, loop->info->limiting_terminator); \
398 EXPECT_EQ(0, loop->info->max_trip_count); \
399 EXPECT_FALSE(loop->info->exact_trip_count_known); \
400 }
401
402 #define INFINITE_LOOP_UNKNOWN_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr) \
403 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _infinite_loop_unknown_count) \
404 { \
405 nir_loop *loop = \
406 loop_builder(&b, {.init_value = _init_value, \
407 .cond_value = _cond_value, \
408 .incr_value = _incr_value, \
409 .cond_instr = nir_ ## cond, \
410 .incr_instr = nir_ ## incr}); \
411 \
412 nir_validate_shader(b.shader, "input"); \
413 \
414 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
415 \
416 ASSERT_NE((void *)0, loop->info); \
417 EXPECT_EQ((void *)0, loop->info->limiting_terminator); \
418 EXPECT_EQ(0, loop->info->max_trip_count); \
419 EXPECT_FALSE(loop->info->exact_trip_count_known); \
420 }
421
422 #define KNOWN_COUNT_TEST_INVERT(_init_value, _incr_value, _cond_value, cond, incr, count) \
423 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _known_count_invert_ ## count) \
424 { \
425 nir_loop *loop = \
426 loop_builder_invert(&b, {.init_value = _init_value, \
427 .incr_value = _incr_value, \
428 .cond_value = _cond_value, \
429 .cond_instr = nir_ ## cond, \
430 .incr_instr = nir_ ## incr}); \
431 \
432 nir_validate_shader(b.shader, "input"); \
433 \
434 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
435 \
436 ASSERT_NE((void *)0, loop->info); \
437 EXPECT_NE((void *)0, loop->info->limiting_terminator); \
438 EXPECT_EQ(count, loop->info->max_trip_count); \
439 EXPECT_TRUE(loop->info->exact_trip_count_known); \
440 \
441 EXPECT_EQ(2, loop->info->num_induction_vars); \
442 ASSERT_NE((void *)0, loop->info->induction_vars); \
443 \
444 const nir_loop_induction_variable *const ivars = \
445 loop->info->induction_vars; \
446 \
447 for (unsigned i = 0; i < loop->info->num_induction_vars; i++) { \
448 EXPECT_NE((void *)0, ivars[i].def); \
449 ASSERT_NE((void *)0, ivars[i].init_src); \
450 EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src)); \
451 ASSERT_NE((void *)0, ivars[i].update_src); \
452 EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src)); \
453 } \
454 }
455
456 #define UNKNOWN_COUNT_TEST_INVERT(_init_value, _incr_value, _cond_value, cond, incr) \
457 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _unknown_count_invert) \
458 { \
459 nir_loop *loop = \
460 loop_builder_invert(&b, {.init_value = _init_value, \
461 .incr_value = _incr_value, \
462 .cond_value = _cond_value, \
463 .cond_instr = nir_ ## cond, \
464 .incr_instr = nir_ ## incr}); \
465 \
466 nir_validate_shader(b.shader, "input"); \
467 \
468 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
469 \
470 ASSERT_NE((void *)0, loop->info); \
471 EXPECT_EQ((void *)0, loop->info->limiting_terminator); \
472 EXPECT_EQ(0, loop->info->max_trip_count); \
473 EXPECT_FALSE(loop->info->exact_trip_count_known); \
474 }
475
476 #define INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(_init_value, _incr_value, _cond_value, cond, incr) \
477 TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _infinite_loop_unknown_count_invert) \
478 { \
479 nir_loop *loop = \
480 loop_builder_invert(&b, {.init_value = _init_value, \
481 .incr_value = _incr_value, \
482 .cond_value = _cond_value, \
483 .cond_instr = nir_ ## cond, \
484 .incr_instr = nir_ ## incr}); \
485 \
486 nir_validate_shader(b.shader, "input"); \
487 \
488 nir_loop_analyze_impl(b.impl, nir_var_all, false); \
489 \
490 ASSERT_NE((void *)0, loop->info); \
491 EXPECT_EQ((void *)0, loop->info->limiting_terminator); \
492 EXPECT_EQ(0, loop->info->max_trip_count); \
493 EXPECT_FALSE(loop->info->exact_trip_count_known); \
494 }
495
496 /* float i = 0.0;
497 * while (true) {
498 * if (i == 0.9)
499 * break;
500 *
501 * i = i + 0.2;
502 * }
503 */
504 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000000, 0x3e4ccccd, 0x3f666666, feq, fadd)
505
506 /* uint i = 1;
507 * while (true) {
508 * if (i != 0)
509 * break;
510 *
511 * i++;
512 * }
513 *
514 * This loop should have an iteration count of zero. See also
515 * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19732#note_1648999
516 */
517 KNOWN_COUNT_TEST(0x00000001, 0x00000000, 0x00000001, ine, iadd, 0)
518
519 /* uint i = 0;
520 * while (true) {
521 * if (i >= 1)
522 * break;
523 *
524 * i++;
525 * }
526 */
527 KNOWN_COUNT_TEST(0x00000000, 0x00000001, 0x00000001, uge, iadd, 1)
528
529 /* uint i = 0;
530 * while (true) {
531 * if (i != 0)
532 * break;
533 *
534 * i++;
535 * }
536 */
537 KNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000001, ine, iadd, 1)
538
539 /* uint i = 0;
540 * while (true) {
541 * if (!(i != 6))
542 * break;
543 *
544 * i++;
545 * }
546 */
547 KNOWN_COUNT_TEST(0x00000000, 0x00000006, 0x00000001, inot_ine, iadd, 6)
548
549 /* uint i = 0;
550 * while (true) {
551 * i++;
552 *
553 * if (!(i != 8))
554 * break;
555 * }
556 */
557 KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000008, inot_ine, iadd, 7)
558
559 /* uint i = 0;
560 * while (true) {
561 * if (i == 1)
562 * break;
563 *
564 * i++;
565 * }
566 */
567 KNOWN_COUNT_TEST(0x00000000, 0x00000001, 0x00000001, ieq, iadd, 1)
568
569 /* uint i = 0;
570 * while (true) {
571 * if (i == 6)
572 * break;
573 *
574 * i++;
575 * }
576 */
577 KNOWN_COUNT_TEST(0x00000000, 0x00000006, 0x00000001, ieq, iadd, 6)
578
579 /* uint i = 0;
580 * while (true) {
581 * i++;
582 *
583 * if (i == 6)
584 * break;
585 * }
586 */
587 KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000006, ieq, iadd, 5)
588
589 /* float i = 0.0;
590 * while (true) {
591 * if (i != 0.0)
592 * break;
593 *
594 * i = i + 1.0;
595 * }
596 */
597 KNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x3f800000, fneu, fadd, 1)
598
599 /* uint i = 0;
600 * while (true) {
601 * i++;
602 *
603 * if (i != 0)
604 * break;
605 * }
606 */
607 KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000000, ine, iadd, 0)
608
609 /* int i = 0;
610 * while (true) {
611 * i++;
612 *
613 * if (i >= 6)
614 * break;
615 * }
616 */
617 KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000006, ige, iadd, 5)
618
619 /* uint i = 10;
620 * while (true) {
621 * if (!(5 < i))
622 * break;
623 *
624 * i += -1;
625 * }
626 */
627 KNOWN_COUNT_TEST(0x0000000a, 0x00000005, 0xffffffff, inot_ilt_rev, iadd, 5)
628
629 /* int i = 10;
630 * while (true) {
631 * if (!(imin(vertex_id, 5) < i))
632 * break;
633 *
634 * i += -1;
635 * }
636 */
637 UNKNOWN_COUNT_TEST(0x0000000a, 0x00000005, 0xffffffff, inot_ilt_imin_rev, iadd)
638
639 /* uint i = 0;
640 * while (true) {
641 * if (!(0 >= i))
642 * break;
643 *
644 * i += 1;
645 * }
646 */
647 KNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000001, inot_uge_rev, iadd, 1)
648
649 /* uint i = 0;
650 * while (true) {
651 * if (i != 0)
652 * break;
653 *
654 * i >>= 1;
655 * }
656 */
657 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000001, ine, ushr)
658
659 /* uint i = 0x80000000;
660 * while (true) {
661 * if (i == 0xDEADBEEF)
662 * break;
663 *
664 * i >>= 1;
665 * }
666 */
667 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x80000000, 0xDEADBEEF, 0x00000001, ieq, ushr)
668
669 /* There is no ult / ushr infinite loop test because, aside from the
670 * contradiction ult(x, 0), there isn't a way to construct such a loop with
671 * the loop induction variable on the left side of the comparison.
672 */
673 /* INFINITE_LOOP_UNKNOWN_COUNT_TEST(0xBADDC0DE, 0xBADDC0DE, 0xBADDC0DE, ult, ushr) */
674
675 /* uint i = 0x40000000;
676 * while (true) {
677 * if (0x43210000 < i)
678 * break;
679 *
680 * i >>= 1;
681 * }
682 */
683 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x40000000, 0x43210000, 0x00000001, ult_rev, ushr)
684
685 /* uint i = 0x40000000;
686 * while (true) {
687 * if (i >= 0x80000000)
688 * break;
689 *
690 * i >>= 1;
691 * }
692 */
693 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x40000000, 0x80000000, 0x00000001, uge, ushr)
694
695 /* There is no uge_rev / ushr infinite loop test because I could not think of
696 * a way to construct one.
697 */
698 /* INFINITE_LOOP_UNKNOWN_COUNT_TEST(0xBADDC0DE, 0xBADDC0DE, 0xBADDC0DE, uge_rev, ushr) */
699
700 /* uint i = 0x00001234;
701 * while (true) {
702 * i >>= 16;
703 *
704 * if (i != 0)
705 * break;
706 * }
707 */
708 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x00001234, 0x00000010, 0x00000000, ine, ushr)
709
710 /* uint i = 0x12345678;
711 * while (true) {
712 * i >>= 3;
713 *
714 * if (i == 0x048d159e)
715 * break;
716 * }
717 */
718 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x12345678, 0x00000003, 0x048d159e, ieq, ushr)
719
720 /* There is no ult / ushr infinite inverted loop test because, aside from the
721 * contradiction ult(x, 0), there isn't a way to construct such a loop with
722 * the loop induction variable on the left side of the comparison.
723 */
724 /* INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xBADDC0DE, 0xBADDC0DE, 0xBADDC0DE, ult, ushr) */
725
726 /* uint i = 0x87654321;
727 * while (true) {
728 * i >>= 2;
729 *
730 * if (0x77777777 < i)
731 * break;
732 * }
733 */
734 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x87654321, 0x00000002, 0x77777777, ult_rev, ushr)
735
736 /* uint i = 0x80000000;
737 * while (true) {
738 * i >>= 3;
739 *
740 * if (i >= 0x40000000)
741 * break;
742 * }
743 */
744 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000003, 0x40000000, uge, ushr)
745
746 /* There is no uge_rev / ushr infinite loop test because I could not think of
747 * a way to construct one.
748 */
749 /* INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xBADDC0DE, 0xBADDC0DE, 0xBADDC0DE, uge_rev, ushr) */
750
751 /* uint i = 0x80000000;
752 * while (true) {
753 * if (i != 0x80000000)
754 * break;
755 *
756 * i >>= 1;
757 * }
758 */
759 KNOWN_COUNT_TEST(0x80000000, 0x80000000, 0x00000001, ine, ushr, 1)
760
761 /* uint i = 0x80000000;
762 * while (true) {
763 * if (i == 0)
764 * break;
765 *
766 * i >>= 1;
767 * }
768 */
769 KNOWN_COUNT_TEST(0x80000000, 0x00000000, 0x00000001, ieq, ushr, 32)
770
771 /* uint i = 0x80000000;
772 * while (true) {
773 * if (i < 2)
774 * break;
775 *
776 * i >>= 1;
777 * }
778 */
779 KNOWN_COUNT_TEST(0x80000000, 0x00000002, 0x00000001, ult, ushr, 31)
780
781 /* uint i = 0x80000000;
782 * while (true) {
783 * if (2 < i)
784 * break;
785 *
786 * i >>= 1;
787 * }
788 */
789 KNOWN_COUNT_TEST(0x80000000, 0x00000002, 0x00000001, ult_rev, ushr, 0)
790
791 /* uint i = 0x80000000;
792 * while (true) {
793 * if (i >= 0x80000000)
794 * break;
795 *
796 * i >>= 1;
797 * }
798 */
799 KNOWN_COUNT_TEST(0x80000000, 0x80000000, 0x00000001, uge, ushr, 0)
800
801 /* uint i = 0x80000000;
802 * while (true) {
803 * if (0x00008000 >= i)
804 * break;
805 *
806 * i >>= 1;
807 * }
808 */
809 KNOWN_COUNT_TEST(0x80000000, 0x00008000, 0x00000001, uge_rev, ushr, 16)
810
811 /* uint i = 0x80000000;
812 * while (true) {
813 * i >>= 1;
814 *
815 * if (i != 0x80000000)
816 * break;
817 * }
818 */
819 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ine, ushr, 0)
820
821 /* uint i = 0x80000000;
822 * while (true) {
823 * i >>= 1;
824 *
825 * if (i == 0x00000000)
826 * break;
827 * }
828 */
829 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, ieq, ushr, 31)
830
831 /* uint i = 0x80000000;
832 * while (true) {
833 * i >>= 1;
834 *
835 * if (i < 0x80000000)
836 * break;
837 * }
838 */
839 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ult, ushr, 0)
840
841 /* uint i = 0xAAAAAAAA;
842 * while (true) {
843 * i >>= 1;
844 *
845 * if (0x08000000 < i)
846 * break;
847 * }
848 */
849 KNOWN_COUNT_TEST_INVERT(0xAAAAAAAA, 0x00000001, 0x08000000, ult_rev, ushr, 0)
850
851 /* uint i = 0x80000000;
852 * while (true) {
853 * i >>= 1;
854 *
855 * if (i >= 0x00000000)
856 * break;
857 * }
858 */
859 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, uge, ushr, 0)
860
861 /* uint i = 0x80000000;
862 * while (true) {
863 * i >>= 1;
864 *
865 * if (0x00000008 >= i)
866 * break;
867 * }
868 */
869 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000008, uge_rev, ushr, 27)
870
871 /* int i = 0xffffffff;
872 * while (true) {
873 * if (i != 0xffffffff)
874 * break;
875 *
876 * i >>= 1;
877 * }
878 */
879 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0xffffffff, 0xffffffff, 0x00000001, ine, ishr)
880
881 /* int i = 0x80000000;
882 * while (true) {
883 * if (i == 0)
884 * break;
885 *
886 * i >>= 1;
887 * }
888 */
889 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x80000000, 0x00000000, 0x00000001, ieq, ishr)
890
891 /* int i = 0x7fffffff;
892 * while (true) {
893 * if (i < 0)
894 * break;
895 *
896 * i >>= 1;
897 * }
898 */
899 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x7fffffff, 0x00000000, 0x00000001, ilt, ishr)
900
901 /* int i = 0x80000000;
902 * while (true) {
903 * if (0 < i)
904 * break;
905 *
906 * i >>= 1;
907 * }
908 */
909 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x80000000, 0x00000000, 0x00000001, ilt_rev, ishr)
910
911 /* int i = 0x80000000;
912 * while (true) {
913 * if (i >= 0)
914 * break;
915 *
916 * i >>= 1;
917 * }
918 */
919 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x80000000, 0x00000000, 0x00000001, ige, ishr)
920
921 /* int i = 0x76543210;
922 * while (true) {
923 * if (-1 >= i)
924 * break;
925 *
926 * i >>= 1;
927 * }
928 */
929 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x76543210, 0xffffffff, 0x00000001, ige_rev, ishr)
930
931 /* int i = 0xffffffff;
932 * while (true) {
933 * i >>= 1;
934 *
935 * if (i != 0xffffffff)
936 * break;
937 * }
938 */
939 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xffffffff, 0x00000001, 0xffffffff, ine, ishr)
940
941 /* int i = 0xffffffff;
942 * while (true) {
943 * i >>= 1;
944 *
945 * if (i == 0)
946 * break;
947 * }
948 */
949 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xffffffff, 0x00000001, 0x00000000, ieq, ishr)
950
951 /* int i = 0x7fffffff;
952 * while (true) {
953 * i >>= 1;
954 *
955 * if (i < 0)
956 * break;
957 * }
958 */
959 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000000, ilt, ishr)
960
961 /* int i = 0x80000000;
962 * while (true) {
963 * i >>= 1;
964 *
965 * if (1 < i)
966 * break;
967 * }
968 */
969 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000001, ilt_rev, ishr)
970
971 /* int i = 0x80000000;
972 * while (true) {
973 * i >>= 1;
974 *
975 * if (i >= 0)
976 * break;
977 * }
978 */
979 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, ige, ishr)
980
981 /* int i = 0x76543210;
982 * while (true) {
983 * i >>= 7;
984 *
985 * if (-1 >= i)
986 * break;
987 * }
988 */
989 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x76543210, 0x00000007, 0xffffffff, ige_rev, ishr)
990
991 /* int i = 0x7fffffff;
992 * while (true) {
993 * if (i != 0)
994 * break;
995 *
996 * i >>= 1;
997 * }
998 */
999 KNOWN_COUNT_TEST(0x7fffffff, 0x00000000, 0x00000001, ine, ishr, 0)
1000
1001 /* int i = 0x40000000;
1002 * while (true) {
1003 * if (i == 1)
1004 * break;
1005 *
1006 * i >>= 1;
1007 * }
1008 */
1009 KNOWN_COUNT_TEST(0x40000000, 0x00000001, 0x00000001, ieq, ishr, 30)
1010
1011 /* int i = 0x7fffffff;
1012 * while (true) {
1013 * if (i < 1)
1014 * break;
1015 *
1016 * i >>= 1;
1017 * }
1018 */
1019 KNOWN_COUNT_TEST(0x7fffffff, 0x00000001, 0x00000001, ilt, ishr, 31)
1020
1021 /* int i = 0x80000000;
1022 * while (true) {
1023 * if (0xffff0000 < i)
1024 * break;
1025 *
1026 * i >>= 1;
1027 * }
1028 */
1029 KNOWN_COUNT_TEST(0x80000000, 0xffff0000, 0x00000001, ilt_rev, ishr, 16)
1030
1031 /* int i = 0x80000000;
1032 * while (true) {
1033 * if (i >= -1)
1034 * break;
1035 *
1036 * i >>= 1;
1037 * }
1038 */
1039 KNOWN_COUNT_TEST(0x80000000, 0xffffffff, 0x00000001, ige, ishr, 31)
1040
1041 /* int i = 0x12345678;
1042 * while (true) {
1043 * if (1 >= i)
1044 * break;
1045 *
1046 * i >>= 4;
1047 * }
1048 */
1049 KNOWN_COUNT_TEST(0x12345678, 0x00000001, 0x00000004, ige_rev, ishr, 7)
1050
1051 /* int i = 0x7fffffff;
1052 * while (true) {
1053 * i >>= 1;
1054 *
1055 * if (i != 0)
1056 * break;
1057 * }
1058 */
1059 KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000000, ine, ishr, 0)
1060
1061 /* int i = 0x7fffffff;
1062 * while (true) {
1063 * i >>= 1;
1064 *
1065 * if (i == 0)
1066 * break;
1067 * }
1068 */
1069 KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000000, ieq, ishr, 30)
1070
1071 /* int i = 0x7fffffff;
1072 * while (true) {
1073 * i >>= 1;
1074 *
1075 * if (i < 1)
1076 * break;
1077 * }
1078 */
1079 KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000001, ilt, ishr, 30)
1080
1081 /* int i = 0x80000000;
1082 * while (true) {
1083 * i >>= 1;
1084 *
1085 * if (-2 < i)
1086 * break;
1087 * }
1088 */
1089 KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0xfffffffe, ilt_rev, ishr, 30)
1090
1091 /* int i = 0xbfffffff;
1092 * while (true) {
1093 * i >>= 1;
1094 *
1095 * if (i >= -2)
1096 * break;
1097 * }
1098 */
1099 KNOWN_COUNT_TEST_INVERT(0xbfffffff, 0x00000001, 0xfffffffe, ige, ishr, 29)
1100
1101 /* int i = 0x7fffffff;
1102 * while (true) {
1103 * i >>= 1;
1104 *
1105 * if (2 >= i)
1106 * break;
1107 * }
1108 */
1109 KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000002, ige_rev, ishr, 29)
1110
1111 /* int i = 0;
1112 * while (true) {
1113 * if (i != 0)
1114 * break;
1115 *
1116 * i <<= 1;
1117 * }
1118 */
1119 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000001, ine, ishl)
1120
1121 /* int i = 1;
1122 * while (true) {
1123 * if (i == 3)
1124 * break;
1125 *
1126 * i <<= 1;
1127 * }
1128 */
1129 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x00000003, 0x00000001, ieq, ishl)
1130
1131 /* int i = 1;
1132 * while (true) {
1133 * if (i < 0x80000001)
1134 * break;
1135 *
1136 * i <<= 2;
1137 * }
1138 */
1139 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x80000001, 0x00000002, ilt, ishl)
1140
1141 /* int i = 0xffff0000;
1142 * while (true) {
1143 * if (1 < i)
1144 * break;
1145 *
1146 * i <<= 2;
1147 * }
1148 */
1149 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0xffff0000, 0x00000001, 0x00000002, ilt_rev, ishl)
1150
1151 /* int i = 1;
1152 * while (true) {
1153 * if (i >= 0x70000000)
1154 * break;
1155 *
1156 * i <<= 1;
1157 * }
1158 */
1159 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x70000000, 0x00000001, ige, ishl)
1160
1161 /* int i = 1;
1162 * while (true) {
1163 * if (0xf0000000 >= i)
1164 * break;
1165 *
1166 * i <<= 2;
1167 * }
1168 */
1169 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0xf0000000, 0x00000002, ige_rev, ishl)
1170
1171 /* int i = 0x80000000;
1172 * while (true) {
1173 * i <<= 1;
1174 *
1175 * if (i != 0)
1176 * break;
1177 * }
1178 */
1179 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, ine, ishl)
1180
1181 /* int i = 0xf0f0f0f0;
1182 * while (true) {
1183 * i <<= 2;
1184 *
1185 * if (i == 0xe1e1e1e0)
1186 * break;
1187 * }
1188 */
1189 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xf0f0f0f0, 0x00000002, 0xe1e1e1e0, ieq, ishl)
1190
1191 /* int i = 1;
1192 * while (true) {
1193 * i <<= 2;
1194 *
1195 * if (i < 0)
1196 * break;
1197 * }
1198 */
1199 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x00000001, 0x00000002, 0x00000000, ilt, ishl)
1200
1201 /* int i = 0xffffffff;
1202 * while (true) {
1203 * i <<= 2;
1204 *
1205 * if (0 < i)
1206 * break;
1207 * }
1208 */
1209 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xffffffff, 0x00000002, 0x00000000, ilt_rev, ishl)
1210
1211 /* int i = 0x88888888;
1212 * while (true) {
1213 * i <<= 4;
1214 *
1215 * if (i >= 1)
1216 * break;
1217 * }
1218 */
1219 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x88888888, 0x00000004, 0x00000001, ige, ishl)
1220
1221 /* int i = 0x77777777;
1222 * while (true) {
1223 * i <<= 4;
1224 *
1225 * if (-1 >= i)
1226 * break;
1227 * }
1228 */
1229 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x77777777, 0x00000004, 0xffffffff, ige_rev, ishl)
1230
1231 /* int i = 1;
1232 * while (true) {
1233 * if (i != 1)
1234 * break;
1235 *
1236 * i <<= 1;
1237 * }
1238 */
1239 KNOWN_COUNT_TEST(0x00000001, 0x00000001, 0x00000001, ine, ishl, 1)
1240
1241 /* int i = 1;
1242 * while (true) {
1243 * if (i == 0x1000)
1244 * break;
1245 *
1246 * i <<= 4;
1247 * }
1248 */
1249 KNOWN_COUNT_TEST(0x00000001, 0x00001000, 0x00000004, ieq, ishl, 3)
1250
1251 /* uint i = 1;
1252 * while (true) {
1253 * if (i < 1)
1254 * break;
1255 *
1256 * i <<= 1;
1257 * }
1258 */
1259 KNOWN_COUNT_TEST(0x00000001, 0x00000001, 0x00000001, ult, ishl, 32)
1260
1261 /* int i = 1;
1262 * while (true) {
1263 * if (i < 1)
1264 * break;
1265 *
1266 * i <<= 1;
1267 * }
1268 */
1269 KNOWN_COUNT_TEST(0x00000001, 0x00000001, 0x00000001, ilt, ishl, 31)
1270
1271 /* int i = 0xffff0000;
1272 * while (true) {
1273 * if (-1 < i)
1274 * break;
1275 *
1276 * i <<= 2;
1277 * }
1278 */
1279 KNOWN_COUNT_TEST(0xffff0000, 0xffffffff, 0x00000002, ilt_rev, ishl, 8)
1280
1281 /* int i = 0xf;
1282 * while (true) {
1283 * if (i >= 0x0000ffff)
1284 * break;
1285 *
1286 * i <<= 3;
1287 * }
1288 */
1289 KNOWN_COUNT_TEST(0x0000000f, 0x0000ffff, 0x00000003, ige, ishl, 5)
1290
1291 /* int i = 0x0000000f;
1292 * while (true) {
1293 * if (-196608 >= i)
1294 * break;
1295 *
1296 * i <<= 4;
1297 * }
1298 */
1299 KNOWN_COUNT_TEST(0x0000000f, 0xfffd0000, 0x00000004, ige_rev, ishl, 7)
1300
1301 /* int i = 1;
1302 * while (true) {
1303 * i <<= 1;
1304 *
1305 * if (i != 2)
1306 * break;
1307 * }
1308 */
1309 KNOWN_COUNT_TEST_INVERT(0x00000001, 0x00000001, 0x00000002, ine, ishl, 1)
1310
1311 /* int i = 1;
1312 * while (true) {
1313 * i <<= 8;
1314 *
1315 * if (i == 0x01000000)
1316 * break;
1317 * }
1318 */
1319 KNOWN_COUNT_TEST_INVERT(0x00000001, 0x00000008, 0x01000000, ieq, ishl, 2)
1320
1321 /* int i = 0x7fffffff;
1322 * while (true) {
1323 * i <<= 1;
1324 *
1325 * if (i < 1)
1326 * break;
1327 * }
1328 */
1329 KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000001, ilt, ishl, 0)
1330
1331 /* int i = 0x7fff;
1332 * while (true) {
1333 * i <<= 2;
1334 *
1335 * if (0x1fffffff < i)
1336 * break;
1337 * }
1338 */
1339 KNOWN_COUNT_TEST_INVERT(0x00007fff, 0x00000002, 0x1fffffff, ilt_rev, ishl, 7)
1340
1341 /* int i = 0xffff7fff;
1342 * while (true) {
1343 * i <<= 4;
1344 *
1345 * if (i >= -2)
1346 * break;
1347 * }
1348 */
1349 KNOWN_COUNT_TEST_INVERT(0xffff7fff, 0x00000004, 0xfffffffe, ige, ishl, 3)
1350
1351 /* int i = 0x0000f0f0;
1352 * while (true) {
1353 * i <<= 4;
1354 *
1355 * if (-2 >= i)
1356 * break;
1357 * }
1358 */
1359 KNOWN_COUNT_TEST_INVERT(0x0000f0f0, 0x00000004, 0xfffffffe, ige_rev, ishl, 3)
1360
1361 /* This infinite loop makes no sense, but it's a good test to make sure the
1362 * loop analysis code doesn't incorrectly treat left-shift as a commutative
1363 * operation.
1364 *
1365 * int i = 1;
1366 * while (true) {
1367 * if (i == 0)
1368 * break;
1369 *
1370 * i = 1 << i;
1371 * }
1372 */
1373 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x00000000, 0x00000001, ieq, ishl_rev)
1374
1375 /* int i = 0;
1376 * while (true) {
1377 * if (i != 0)
1378 * break;
1379 *
1380 * i = i * 7;
1381 * }
1382 */
1383 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000007, ine, imul)
1384
1385 /* int i = 1;
1386 * while (true) {
1387 * if (i == 4)
1388 * break;
1389 *
1390 * i = i * 3;
1391 * }
1392 */
1393 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x00000004, 0x00000003, ieq, imul)
1394
1395 /* int i = 1;
1396 * while (true) {
1397 * // The only value less than 0x80000001 is 0x80000000, but the result
1398 * // of the multiply can never be even.
1399 * if (i < 0x80000001)
1400 * break;
1401 *
1402 * i = i * 5;
1403 * }
1404 */
1405 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000001, 0x80000001, 0x00000005, ilt, imul)
1406
1407 /* int i = 2;
1408 * while (true) {
1409 * if (i >= 0x7f000000)
1410 * break;
1411 *
1412 * i = i * 6;
1413 * }
1414 */
1415 INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000002, 0x7f000000, 0x00000006, ige, imul)
1416
1417 /* int i = 0x80000000;
1418 * while (true) {
1419 * i = i * 6;
1420 *
1421 * if (i != 0)
1422 * break;
1423 * }
1424 */
1425 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000006, 0x00000000, ine, imul)
1426
1427 /* int i = 0xf0f0f0f0;
1428 * while (true) {
1429 * i = i * 6;
1430 *
1431 * if (i == 0xe1e1e1e1)
1432 * break;
1433 * }
1434 */
1435 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0xf0f0f0f0, 0x00000006, 0xe1e1e1e1, ieq, imul)
1436
1437 /* int i = 3;
1438 * while (true) {
1439 * i = i * 3;
1440 *
1441 * // The only value less than 0x80000001 is 0x80000000, but the result
1442 * // of the multiply can never be even.
1443 * if (i < 0x80000001)
1444 * break;
1445 * }
1446 */
1447 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x00000003, 0x00000003, 0x80000001, ilt, imul)
1448
1449 /* int i = 0x88888888;
1450 * while (true) {
1451 * i = i * 16;
1452 *
1453 * if (i >= 1)
1454 * break;
1455 * }
1456 *
1457 * I'm not fond of this test because (i * 16) is the same as (i << 4), but I
1458 * could not think of another way.
1459 */
1460 INFINITE_LOOP_UNKNOWN_COUNT_TEST_INVERT(0x88888888, 0x00000010, 0x00000001, ige, imul)
1461
1462 /* int i = 1;
1463 * while (true) {
1464 * if (i != 1)
1465 * break;
1466 *
1467 * i = i * 7;
1468 * }
1469 */
1470 KNOWN_COUNT_TEST(0x00000001, 0x00000001, 0x00000007, ine, imul, 1)
1471
1472 /* int i = 2;
1473 * while (true) {
1474 * if (i == 54)
1475 * break;
1476 *
1477 * i = i * 3;
1478 * }
1479 */
1480 KNOWN_COUNT_TEST(0x00000002, 0x00000036, 0x00000003, ieq, imul, 3)
1481
1482 /* int i = 5;
1483 * while (true) {
1484 * if (i < 1)
1485 * break;
1486 *
1487 * i = i * -3;
1488 * }
1489 */
1490 KNOWN_COUNT_TEST(0x00000005, 0x00000001, 0xfffffffd, ilt, imul, 1)
1491
1492 /* int i = 0xf;
1493 * while (true) {
1494 * if (i >= 0x0000ffff)
1495 * break;
1496 *
1497 * i = i * 11;
1498 * }
1499 */
1500 KNOWN_COUNT_TEST(0x0000000f, 0x0000ffff, 0x0000000b, ige, imul, 4)
1501
1502 /* int i = 3;
1503 * while (true) {
1504 * i = i * -5;
1505 *
1506 * if (i != -15)
1507 * break;
1508 * }
1509 */
1510 KNOWN_COUNT_TEST_INVERT(0x00000003, 0xfffffffb, 0xfffffff1, ine, imul, 1)
1511
1512 /* int i = 3;
1513 * while (true) {
1514 * i = i * -7;
1515 *
1516 * if (i == 0x562b3)
1517 * break;
1518 * }
1519 */
1520 KNOWN_COUNT_TEST_INVERT(0x00000003, 0xfffffff9, 0x000562b3, ieq, imul, 5)
1521
1522 /* int i = 0x7f;
1523 * while (true) {
1524 * i = i * 3;
1525 *
1526 * if (i < 1)
1527 * break;
1528 * }
1529 */
1530 KNOWN_COUNT_TEST_INVERT(0x0000007f, 0x00000003, 0x00000001, ilt, imul, 16)
1531
1532 /* int i = 0xffff7fff;
1533 * while (true) {
1534 * i = i * 15;
1535 *
1536 * if (i >= 0x34cce9b0)
1537 * break;
1538 * }
1539 */
1540 KNOWN_COUNT_TEST_INVERT(0xffff7fff, 0x0000000f, 0x34cce9b0, ige, imul, 4)
1541
1542 /* int i = 0;
1543 * while (true) {
1544 * if (i >= imin(vertex_id, 4))
1545 * break;
1546 *
1547 * i++;
1548 * }
1549 */
1550 INEXACT_COUNT_TEST(0x00000000, 0x00000004, 0x00000001, ige_imin, iadd, 4)
1551
1552 /* This fmin is the wrong type to be useful.
1553 *
1554 * int i = 0;
1555 * while (true) {
1556 * if (i >= fmin(vertex_id, 4))
1557 * break;
1558 *
1559 * i++;
1560 * }
1561 */
1562 UNKNOWN_COUNT_TEST(0x00000000, 0x00000004, 0x00000001, ige_fmin, iadd)
1563
1564 /* The comparison is unsigned, so this isn't safe if vertex_id is negative.
1565 *
1566 * uint i = 0;
1567 * while (true) {
1568 * if (i >= imin(vertex_id, 4))
1569 * break;
1570 *
1571 * i++;
1572 * }
1573 */
1574 UNKNOWN_COUNT_TEST(0x00000000, 0x00000004, 0x00000001, uge_imin, iadd)
1575
1576 /* int i = 8;
1577 * while (true) {
1578 * if (4 >= i)
1579 * break;
1580 *
1581 * i += -1;
1582 * }
1583 */
1584 KNOWN_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ige_rev, iadd, 4)
1585
1586 /* int i = 8;
1587 * while (true) {
1588 * if (i < 4)
1589 * break;
1590 *
1591 * i += -1;
1592 * }
1593 */
1594 KNOWN_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ilt, iadd, 5)
1595
1596 /* This imin can increase the iteration count, not limit it.
1597 *
1598 * int i = 8;
1599 * while (true) {
1600 * if (imin(vertex_id, 4) >= i)
1601 * break;
1602 *
1603 * i += -1;
1604 * }
1605 */
1606 UNKNOWN_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ige_imin_rev, iadd)
1607
1608 /* This imin can increase the iteration count, not limit it.
1609 *
1610 * int i = 8;
1611 * while (true) {
1612 * if (i < imin(vertex_id, 4))
1613 * break;
1614 *
1615 * i += -1;
1616 * }
1617 */
1618 UNKNOWN_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ilt_imin, iadd)
1619
1620 /* int i = 8;
1621 * while (true) {
1622 * if (i < imax(vertex_id, 4))
1623 * break;
1624 *
1625 * i--;
1626 * }
1627 */
1628 INEXACT_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ilt_imax, iadd, 5)
1629
1630 /* uint i = 0x00000001;
1631 * while (true) {
1632 * if (i >= umin(vertex_id, 0x00000100))
1633 * break;
1634 *
1635 * i <<= 1;
1636 * }
1637 */
1638 INEXACT_COUNT_TEST(0x00000001, 0x00000100, 0x00000001, uge_umin, ishl, 8)
1639