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