nir/tests: Port almost all loop_analyze tests to new macro-based infastructure
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 17 Feb 2023 20:20:09 +0000 (12:20 -0800)
committerMarge Bot <emma+marge@anholt.net>
Thu, 6 Apr 2023 23:50:27 +0000 (23:50 +0000)
The one test that remains would have an automatically generated name
that would conflict with another test. This test is also a little
special (per the comment in the test), so it's probably best to leave it
separate anyway.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3445>

src/compiler/nir/tests/loop_analyze_tests.cpp

index 6f79a0a..8454f5e 100644 (file)
@@ -185,484 +185,6 @@ loop_builder_invert(nir_builder *b, loop_builder_invert_param p)
    return loop;
 }
 
-TEST_F(nir_loop_analyze_test, infinite_loop_feq)
-{
-   /* Create IR:
-    *
-    *    float i = 0.0;
-    *    while (true) {
-    *       if (i == 0.9)
-    *          break;
-    *
-    *       i = i + 0.2;
-    *    }
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000000, .cond_value = 0x3e4ccccd,
-                        .incr_value = 0x3f666666,
-                        .cond_instr = nir_feq, .incr_instr = nir_fadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x3e4ccccd = 0.900000)
-    *         vec1 32 ssa_2 = load_const (0x3f666666 = 0.200000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = feq ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = fadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_FALSE(loop->info->guessed_trip_count);
-   EXPECT_FALSE(loop->info->exact_trip_count_known);
-   EXPECT_EQ((void *)0, loop->info->limiting_terminator);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, zero_iterations_ine)
-{
-   /* Create IR:
-    *
-    *    uint i = 1;
-    *    while (true) {
-    *       if (i != 0)
-    *          break;
-    *
-    *       i++;
-    *    }
-    *
-    * This loop should have an iteration count of zero.  See also
-    * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19732#note_1648999
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000001, .cond_value = 0x00000000,
-                        .incr_value = 0x00000001,
-                        .cond_instr = nir_ine, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000001 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000001 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = ine ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = iadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(0, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, one_iteration_uge)
-{
-   /* Create IR:
-    *
-    *    uint i = 0;
-    *    while (true) {
-    *       if (i >= 1)
-    *          break;
-    *
-    *       i++;
-    *    }
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000000, .cond_value = 0x00000001,
-                        .incr_value = 0x00000001,
-                        .cond_instr = nir_uge, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000001 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000001 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = uge ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = iadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(1, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, one_iteration_ine)
-{
-   /* Create IR:
-    *
-    *    uint i = 0;
-    *    while (true) {
-    *       if (i != 0)
-    *          break;
-    *
-    *       i++;
-    *    }
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000000, .cond_value = 0x00000000,
-                        .incr_value = 0x00000001,
-                        .cond_instr = nir_ine, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000001 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = ine ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = iadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(1, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, one_iteration_ieq)
-{
-   /* Create IR:
-    *
-    *    uint i = 0;
-    *    while (true) {
-    *       if (i == 1)
-    *          break;
-    *
-    *       i++;
-    *    }
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000000, .cond_value = 0x00000001,
-                        .incr_value = 0x00000001,
-                        .cond_instr = nir_ieq, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000001 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000001 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = ieq ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = iadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(1, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, one_iteration_easy_fneu)
-{
-   /* Create IR:
-    *
-    *    float i = 0.0;
-    *    while (true) {
-    *       if (i != 0.0)
-    *          break;
-    *
-    *       i = i + 1.0;
-    *    }
-    */
-   nir_loop *loop =
-      loop_builder(&b, {.init_value = 0x00000000, .cond_value = 0x00000000,
-                        .incr_value = 0x3f800000,
-                        .cond_instr = nir_fneu, .incr_instr = nir_fadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x3f800000 = 1.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1  1 ssa_3 = fneu ssa_5, ssa_1
-    *                 // succs: block_2 block_3
-    *                 if ssa_3 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 vec1 32 ssa_4 = fadd ssa_5, ssa_2
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(1, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_4. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
 TEST_F(nir_loop_analyze_test, one_iteration_fneu)
 {
    /* Create IR:
@@ -747,168 +269,6 @@ TEST_F(nir_loop_analyze_test, one_iteration_fneu)
    }
 }
 
-TEST_F(nir_loop_analyze_test, zero_iterations_ine_inverted)
-{
-   /* Create IR:
-    *
-    *    uint i = 0;
-    *    while (true) {
-    *       i++;
-    *
-    *       if (i != 0)
-    *          break;
-    *    }
-    *
-    * This loop should have an iteration count of zero.
-    */
-   nir_loop *loop =
-      loop_builder_invert(&b, {.init_value = 0x00000000, .incr_value = 0x00000001,
-                               .cond_value = 0x00000000,
-                               .cond_instr = nir_ine, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000001 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000000 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1 32 ssa_3 = iadd ssa_5, ssa_1
-    *                 vec1  1 ssa_4 = ine ssa_3, ssa_2
-    *                 // succs: block_2 block_3
-    *                 if ssa_4 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(0, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_3. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
-TEST_F(nir_loop_analyze_test, five_iterations_ige_inverted)
-{
-   /* Create IR:
-    *
-    *    int i = 0;
-    *    while (true) {
-    *       i++;
-    *
-    *       if (i >= 6)
-    *          break;
-    *    }
-    *
-    * This loop should have an iteration count of 5.
-    */
-   nir_loop *loop =
-      loop_builder_invert(&b, {.init_value = 0x00000000, .incr_value = 0x00000001,
-                               .cond_value = 0x00000006,
-                               .cond_instr = nir_ige, .incr_instr = nir_iadd});
-
-   /* At this point, we should have:
-    *
-    * impl main {
-    *         block block_0:
-    *         // preds:
-    *         vec1 32 ssa_0 = load_const (0x00000000 = 0.000000)
-    *         vec1 32 ssa_1 = load_const (0x00000001 = 0.000000)
-    *         vec1 32 ssa_2 = load_const (0x00000006 = 0.000000)
-    *         // succs: block_1
-    *         loop {
-    *                 block block_1:
-    *                 // preds: block_0 block_4
-    *                 vec1 32 ssa_5 = phi block_0: ssa_0, block_4: ssa_4
-    *                 vec1 32 ssa_3 = iadd ssa_5, ssa_1
-    *                 vec1  1 ssa_4 = ilt ssa_3, ssa_2
-    *                 // succs: block_2 block_3
-    *                 if ssa_4 {
-    *                         block block_2:
-    *                         // preds: block_1
-    *                         break
-    *                         // succs: block_5
-    *                 } else {
-    *                         block block_3:
-    *                         // preds: block_1
-    *                         // succs: block_4
-    *                 }
-    *                 block block_4:
-    *                 // preds: block_3
-    *                 // succs: block_1
-    *         }
-    *         block block_5:
-    *         // preds: block_2
-    *         // succs: block_6
-    *         block block_6:
-    * }
-    */
-   nir_validate_shader(b.shader, "input");
-
-   nir_loop_analyze_impl(b.impl, nir_var_all, false);
-
-   ASSERT_NE((void *)0, loop->info);
-   EXPECT_EQ(5, loop->info->max_trip_count);
-   EXPECT_TRUE(loop->info->exact_trip_count_known);
-
-   /* Loop should have an induction variable for ssa_5 and ssa_3. */
-   EXPECT_EQ(2, loop->info->num_induction_vars);
-   ASSERT_NE((void *)0, loop->info->induction_vars);
-
-   /* The def field should not be NULL. The init_src field should point to a
-    * load_const. The update_src field should point to a load_const.
-    */
-   const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
-
-   for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
-      EXPECT_NE((void *)0, ivars[i].def);
-      ASSERT_NE((void *)0, ivars[i].init_src);
-      EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
-      ASSERT_NE((void *)0, ivars[i].update_src);
-      EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
-   }
-}
-
 #define COMPARE_REVERSE(comp)                                           \
    static nir_ssa_def *                                                 \
    nir_ ## comp ## _rev(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) \
@@ -1079,6 +439,89 @@ INOT_COMPARE(ilt_rev)
       EXPECT_FALSE(loop->info->exact_trip_count_known);                 \
    }
 
+/*    float i = 0.0;
+ *    while (true) {
+ *       if (i == 0.9)
+ *          break;
+ *
+ *       i = i + 0.2;
+ *    }
+ */
+INFINITE_LOOP_UNKNOWN_COUNT_TEST(0x00000000, 0x3e4ccccd, 0x3f666666, feq, fadd)
+
+/*    uint i = 1;
+ *    while (true) {
+ *       if (i != 0)
+ *          break;
+ *
+ *       i++;
+ *    }
+ *
+ * This loop should have an iteration count of zero.  See also
+ * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19732#note_1648999
+ */
+KNOWN_COUNT_TEST(0x00000001, 0x00000000, 0x00000001, ine, iadd, 0)
+
+/*    uint i = 0;
+ *    while (true) {
+ *       if (i >= 1)
+ *          break;
+ *
+ *       i++;
+ *    }
+ */
+KNOWN_COUNT_TEST(0x00000000, 0x00000001, 0x00000001, uge, iadd, 1)
+
+/*    uint i = 0;
+ *    while (true) {
+ *       if (i != 0)
+ *          break;
+ *
+ *       i++;
+ *    }
+ */
+KNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x00000001, ine, iadd, 1)
+
+/*    uint i = 0;
+ *    while (true) {
+ *       if (i == 1)
+ *          break;
+ *
+ *       i++;
+ *    }
+ */
+KNOWN_COUNT_TEST(0x00000000, 0x00000001, 0x00000001, ieq, iadd, 1)
+
+/*    float i = 0.0;
+ *    while (true) {
+ *       if (i != 0.0)
+ *          break;
+ *
+ *       i = i + 1.0;
+ *    }
+ */
+KNOWN_COUNT_TEST(0x00000000, 0x00000000, 0x3f800000, fneu, fadd, 1)
+
+/*    uint i = 0;
+ *    while (true) {
+ *       i++;
+ *
+ *       if (i != 0)
+ *          break;
+ *    }
+ */
+KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000000, ine, iadd, 0)
+
+/*    int i = 0;
+ *    while (true) {
+ *       i++;
+ *
+ *       if (i >= 6)
+ *          break;
+ *    }
+ */
+KNOWN_COUNT_TEST_INVERT(0x00000000, 0x00000001, 0x00000006, ige, iadd, 5)
+
 /*    uint i = 10;
  *    while (true) {
  *       if (!(5 < i))