mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
nir/tests: Port almost all loop_analyze tests to new macro-based infastructure
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>
This commit is contained in:
parent
9427aaeab7
commit
72a9d12c96
1 changed files with 83 additions and 640 deletions
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue