nir/loop_analyze: Change invert_cond instead of changing the condition

This ensures that scenarios like
nir_loop_analyze_test.iadd_inot_ilt_rev_known_count_5 don't regress in
the next commit. It also means we don't change float comparisons. These
are probably fine... but it still made me a little uneasy.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3445>
This commit is contained in:
Ian Romanick
2023-02-14 16:12:23 -08:00
committed by Marge Bot
parent aeb8af1141
commit 99a7a6648d
2 changed files with 60 additions and 3 deletions

View File

@@ -1236,6 +1236,8 @@ find_trip_count(loop_info_state *state, unsigned execution_mode)
nir_op alu_op = nir_ssa_scalar_alu_op(cond);
bool invert_cond = terminator->continue_from_then;
bool limit_rhs;
nir_ssa_scalar basic_ind = { NULL, 0 };
nir_ssa_scalar limit;
@@ -1247,7 +1249,8 @@ find_trip_count(loop_info_state *state, unsigned execution_mode)
* inverse of x or y (i.e. which ever contained the induction var) in
* order to compute the trip count.
*/
alu_op = inverse_comparison(nir_ssa_scalar_alu_op(cond));
alu_op = nir_ssa_scalar_alu_op(cond);
invert_cond = !invert_cond;
trip_count_known = false;
terminator->exact_trip_count_unknown = true;
}
@@ -1258,7 +1261,8 @@ find_trip_count(loop_info_state *state, unsigned execution_mode)
*/
if (alu_op == nir_op_inot) {
cond = nir_ssa_scalar_chase_alu_src(cond, 0);
alu_op = inverse_comparison(nir_ssa_scalar_alu_op(cond));
alu_op = nir_ssa_scalar_alu_op(cond);
invert_cond = !invert_cond;
}
get_induction_and_limit_vars(cond, &basic_ind,
@@ -1329,7 +1333,7 @@ find_trip_count(loop_info_state *state, unsigned execution_mode)
nir_instr_as_alu(lv->update_src->src.parent_instr),
cond,
alu_op, limit_rhs,
terminator->continue_from_then,
invert_cond,
execution_mode);
/* Where we not able to calculate the iteration count */

View File

@@ -918,6 +918,49 @@ COMPARE_REVERSE(ige)
COMPARE_REVERSE(ult)
COMPARE_REVERSE(uge)
#define INOT_COMPARE(comp) \
static nir_ssa_def * \
nir_inot_ ## comp (nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) \
{ \
return nir_inot(b, nir_ ## comp (b, x, y)); \
}
INOT_COMPARE(ilt_rev)
#define KNOWN_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr, count) \
TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _known_count_ ## count) \
{ \
nir_loop *loop = \
loop_builder(&b, {.init_value = _init_value, \
.cond_value = _cond_value, \
.incr_value = _incr_value, \
.cond_instr = nir_ ## cond, \
.incr_instr = nir_ ## incr}); \
\
nir_validate_shader(b.shader, "input"); \
\
nir_loop_analyze_impl(b.impl, nir_var_all, false); \
\
ASSERT_NE((void *)0, loop->info); \
EXPECT_NE((void *)0, loop->info->limiting_terminator); \
EXPECT_EQ(count, loop->info->max_trip_count); \
EXPECT_TRUE(loop->info->exact_trip_count_known); \
\
EXPECT_EQ(2, loop->info->num_induction_vars); \
ASSERT_NE((void *)0, loop->info->induction_vars); \
\
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 UNKNOWN_COUNT_TEST(_init_value, _cond_value, _incr_value, cond, incr) \
TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _unknown_count) \
{ \
@@ -998,6 +1041,16 @@ COMPARE_REVERSE(uge)
EXPECT_FALSE(loop->info->exact_trip_count_known); \
}
/* uint i = 10;
* while (true) {
* if (!(5 < i))
* break;
*
* i += -1;
* }
*/
KNOWN_COUNT_TEST(0x0000000a, 0x00000005, 0xffffffff, inot_ilt_rev, iadd, 5)
/* uint i = 0;
* while (true) {
* if (i != 0)