• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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