Module: Mesa Branch: main Commit: 0cbe0d2968cbea9f036857e3463b86a8a114b66c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0cbe0d2968cbea9f036857e3463b86a8a114b66c
Author: Rhys Perry <pendingchao...@gmail.com> Date: Wed Nov 15 19:14:50 2023 +0000 nir/loop_analyze: support loops with min/max and non-add incrementation Signed-off-by: Rhys Perry <pendingchao...@gmail.com> Acked-by: Timothy Arceri <tarc...@itsqueeze.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26225> --- src/compiler/nir/nir_loop_analyze.c | 19 +++++++++++-------- src/compiler/nir/tests/loop_analyze_tests.cpp | 11 +++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c index 8146070e941..293f83c6767 100644 --- a/src/compiler/nir/nir_loop_analyze.c +++ b/src/compiler/nir/nir_loop_analyze.c @@ -959,20 +959,23 @@ get_iteration(nir_op cond_op, nir_const_value initial, nir_const_value step, 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 @@ get_iteration_empirical(nir_scalar cond, nir_alu_instr *incr_alu, 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 @@ calculate_iterations(nir_scalar basis, nir_scalar limit_basis, 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 b9a2c5e0a67..24415c9b2a7 100644 --- a/src/compiler/nir/tests/loop_analyze_tests.cpp +++ b/src/compiler/nir/tests/loop_analyze_tests.cpp @@ -302,6 +302,7 @@ INOT_COMPARE(ine) 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 @@ UNKNOWN_COUNT_TEST(0x00000008, 0x00000004, 0xffffffff, ilt_imin, iadd) * } */ 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)