Module: Mesa
Branch: main
Commit: 99a7a6648de38f79aa06dabad010ec191aae18f4
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=99a7a6648de38f79aa06dabad010ec191aae18f4

Author: Ian Romanick <[email protected]>
Date:   Tue Feb 14 16:12:23 2023 -0800

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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3445>

---

 src/compiler/nir/nir_loop_analyze.c           | 10 +++--
 src/compiler/nir/tests/loop_analyze_tests.cpp | 53 +++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/src/compiler/nir/nir_loop_analyze.c 
b/src/compiler/nir/nir_loop_analyze.c
index d998ec6f019..a439bcc19db 100644
--- a/src/compiler/nir/nir_loop_analyze.c
+++ b/src/compiler/nir/nir_loop_analyze.c
@@ -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 */
diff --git a/src/compiler/nir/tests/loop_analyze_tests.cpp 
b/src/compiler/nir/tests/loop_analyze_tests.cpp
index 1fdf10df595..9b39a6653f9 100644
--- a/src/compiler/nir/tests/loop_analyze_tests.cpp
+++ b/src/compiler/nir/tests/loop_analyze_tests.cpp
@@ -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)

Reply via email to