nir/loop_analyze: support loops with min/max and non-add incrementation
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Acked-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26225>
diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c
index 8146070..293f83c 100644
--- a/src/compiler/nir/nir_loop_analyze.c
+++ b/src/compiler/nir/nir_loop_analyze.c
@@ -959,20 +959,23 @@
static int32_t
get_iteration_empirical(nir_scalar cond, nir_alu_instr *incr_alu,
nir_scalar basis, nir_const_value initial,
+ nir_scalar limit_basis, nir_const_value limit,
bool invert_cond, unsigned execution_mode,
unsigned max_unroll_iterations)
{
int iter_count = 0;
nir_const_value result;
- nir_const_value iter = initial;
const nir_scalar incr = nir_get_scalar(&incr_alu->def, basis.comp);
+ const nir_scalar original[] = {basis, limit_basis};
+ nir_const_value replacement[] = {initial, limit};
+
while (iter_count <= max_unroll_iterations) {
bool success;
- success = try_eval_const_alu(&result, cond, &basis, &iter,
- 1, execution_mode);
+ success = try_eval_const_alu(&result, cond, original, replacement,
+ 2, execution_mode);
if (!success)
return -1;
@@ -982,11 +985,11 @@
iter_count++;
- success = try_eval_const_alu(&result, incr, &basis, &iter,
- 1, execution_mode);
+ success = try_eval_const_alu(&result, incr, original, replacement,
+ 2, execution_mode);
assert(success);
- iter = result;
+ replacement[0] = result;
}
return -1;
@@ -1141,8 +1144,8 @@
case nir_op_ishr:
case nir_op_ushr:
return get_iteration_empirical(cond, alu, basis, initial,
- invert_cond, execution_mode,
- max_unroll_iterations);
+ limit_basis, limit, invert_cond,
+ execution_mode, max_unroll_iterations);
default:
unreachable("Invalid induction variable increment operation.");
}
diff --git a/src/compiler/nir/tests/loop_analyze_tests.cpp b/src/compiler/nir/tests/loop_analyze_tests.cpp
index b9a2c5e..24415c9 100644
--- a/src/compiler/nir/tests/loop_analyze_tests.cpp
+++ b/src/compiler/nir/tests/loop_analyze_tests.cpp
@@ -302,6 +302,7 @@
CMP_MIN(ige, imin)
CMP_MIN_REV(ige, imin)
+CMP_MIN(uge, umin)
CMP_MIN(ige, fmin)
CMP_MIN(uge, imin)
CMP_MIN(ilt, imin)
@@ -1614,3 +1615,13 @@
* }
*/
INEXACT_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ilt_imax, iadd, 5)
+
+/* uint i = 0x00000001;
+ * while (true) {
+ * if (i >= umin(vertex_id, 0x00000100))
+ * break;
+ *
+ * i <<= 1;
+ * }
+ */
+INEXACT_COUNT_TEST(0x00000001, 0x00000100, 0x00000001, uge_umin, ishl, 8)