xref: /aosp_15_r20/external/mesa3d/src/compiler/nir/tests/loop_analyze_tests.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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