nir_alu_instr *alu = nir_instr_as_alu(src_var->def->parent_instr);
/* Check for unsupported alu operations */
- if (alu->op != nir_op_iadd && alu->op != nir_op_fadd)
+ if (alu->op != nir_op_iadd && alu->op != nir_op_fadd &&
+ alu->op != nir_op_imul && alu->op != nir_op_fmul &&
+ alu->op != nir_op_ishl && alu->op != nir_op_ishr &&
+ alu->op != nir_op_ushr)
break;
if (nir_op_infos[alu->op].num_inputs == 2) {
induction_base_type);
}
- /* Only variable with these update ops were marked as induction. */
- assert(alu->op == nir_op_iadd || alu->op == nir_op_fadd);
-
/* do-while loops can increment the starting value before the condition is
* checked. e.g.
*
trip_offset = 1;
}
- assert(nir_src_bit_size(alu->src[0].src) ==
- nir_src_bit_size(alu->src[1].src));
unsigned bit_size = nir_src_bit_size(alu->src[0].src);
/* get_iteration works under assumption that iterator will be
return 0;
}
- int iter_int = get_iteration(alu_op, initial, step, limit, bit_size,
- execution_mode);
+ int iter_int;
+ switch (alu->op) {
+ case nir_op_iadd:
+ case nir_op_fadd:
+ assert(nir_src_bit_size(alu->src[0].src) ==
+ nir_src_bit_size(alu->src[1].src));
+
+ iter_int = get_iteration(alu_op, initial, step, limit, bit_size,
+ execution_mode);
+ break;
+ case nir_op_imul:
+ case nir_op_fmul:
+ case nir_op_ishl:
+ case nir_op_ishr:
+ case nir_op_ushr:
+ return -1;
+ default:
+ unreachable("Invalid induction variable increment operation.");
+ }
/* If iter_int is negative the loop is ill-formed or is the conditional is
* unsigned with a huge iteration count so don't bother going any further.
EXPECT_FALSE(loop->info->exact_trip_count_known); \
}
+#define KNOWN_COUNT_TEST_INVERT(_init_value, _incr_value, _cond_value, cond, incr, count) \
+ TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _known_count_invert_ ## count) \
+ { \
+ nir_loop *loop = \
+ loop_builder_invert(&b, {.init_value = _init_value, \
+ .incr_value = _incr_value, \
+ .cond_value = _cond_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_INVERT(_init_value, _incr_value, _cond_value, cond, incr) \
TEST_F(nir_loop_analyze_test, incr ## _ ## cond ## _unknown_count_invert) \
{ \
* i >>= 1;
* }
*/
-UNKNOWN_COUNT_TEST(0x80000000, 0x00000002, 0x00000001, ult_rev, ushr)
+KNOWN_COUNT_TEST(0x80000000, 0x00000002, 0x00000001, ult_rev, ushr, 0)
/* uint i = 0x80000000;
* while (true) {
* i >>= 1;
* }
*/
-UNKNOWN_COUNT_TEST(0x80000000, 0x80000000, 0x00000001, uge, ushr)
+KNOWN_COUNT_TEST(0x80000000, 0x80000000, 0x00000001, uge, ushr, 0)
/* uint i = 0x80000000;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ine, ushr)
+KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ine, ushr, 0)
/* uint i = 0x80000000;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ult, ushr)
+KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x80000000, ult, ushr, 0)
/* uint i = 0xAAAAAAAA;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0xAAAAAAAA, 0x00000001, 0x08000000, ult_rev, ushr)
+KNOWN_COUNT_TEST_INVERT(0xAAAAAAAA, 0x00000001, 0x08000000, ult_rev, ushr, 0)
/* uint i = 0x80000000;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, uge, ushr)
+KNOWN_COUNT_TEST_INVERT(0x80000000, 0x00000001, 0x00000000, uge, ushr, 0)
/* uint i = 0x80000000;
* while (true) {
* i >>= 1;
* }
*/
-UNKNOWN_COUNT_TEST(0x7fffffff, 0x00000000, 0x00000001, ine, ishr)
+KNOWN_COUNT_TEST(0x7fffffff, 0x00000000, 0x00000001, ine, ishr, 0)
/* int i = 0x40000000;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000000, ine, ishr)
+KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000000, ine, ishr, 0)
/* int i = 0x7fffffff;
* while (true) {
* break;
* }
*/
-UNKNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000001, ilt, ishl)
+KNOWN_COUNT_TEST_INVERT(0x7fffffff, 0x00000001, 0x00000001, ilt, ishl, 0)
/* int i = 0x7fff;
* while (true) {