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:
@@ -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 */
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user