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

Author: Ian Romanick <[email protected]>
Date:   Tue Sep  6 10:28:14 2022 -0700

nir/comparison_pre: See through an inot to apply the optimization

This also prevents some small regressions in "glsl: remove GLSL IR
inverse comparison optimisations".

shader-db results:

All Sandy Bridge and newer Intel platforms had similar results. (Ice Lake shown)
total instructions in shared programs: 19941025 -> 19940805 (<.01%)
instructions in affected programs: 52431 -> 52211 (-0.42%)
helped: 188 / HURT: 6

total cycles in shared programs: 858451784 -> 858431633 (<.01%)
cycles in affected programs: 2119134 -> 2098983 (-0.95%)
helped: 183 / HURT: 12

LOST:   2
GAINED: 0

Iron Lake and GM45 had similar results. (Iron Lake shown)
total instructions in shared programs: 8364668 -> 8364670 (<.01%)
instructions in affected programs: 753 -> 755 (0.27%)
helped: 2 / HURT: 4

total cycles in shared programs: 248752572 -> 248752238 (<.01%)
cycles in affected programs: 87290 -> 86956 (-0.38%)
helped: 2 / HURT: 4

fossil-db results:

Skylake, Ice Lake, and Tiger Lake had similar results. (Ice Lake shown)
Instructions in all programs: 144909184 -> 144909130 (-0.0%)
Instructions helped: 6

Cycles in all programs: 9138641740 -> 9138640984 (-0.0%)
Cycles helped: 8

Reviewed-by: Timothy Arceri <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18006>

---

 src/compiler/nir/nir_opt_comparison_pre.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir_opt_comparison_pre.c 
b/src/compiler/nir/nir_opt_comparison_pre.c
index 19516a5061d..d8b08ff706f 100644
--- a/src/compiler/nir/nir_opt_comparison_pre.c
+++ b/src/compiler/nir/nir_opt_comparison_pre.c
@@ -133,6 +133,34 @@ add_instruction_for_block(struct block_instructions *bi,
    *data = alu;
 }
 
+/**
+ * Determine if the ALU instruction is used by an if-condition or used by a
+ * logic-not that is used by an if-condition.
+ */
+static bool
+is_compatible_condition(const nir_alu_instr *instr)
+{
+   if (is_used_by_if(instr))
+      return true;
+
+   nir_foreach_use(src, &instr->dest.dest.ssa) {
+      const nir_instr *const user_instr = src->parent_instr;
+
+      if (user_instr->type != nir_instr_type_alu)
+         continue;
+
+      const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr);
+
+      if (user_alu->op != nir_op_inot)
+         continue;
+
+      if (is_used_by_if(user_alu))
+         return true;
+   }
+
+   return false;
+}
+
 static void
 rewrite_compare_instruction(nir_builder *bld, nir_alu_instr *orig_cmp,
                             nir_alu_instr *orig_add, bool zero_on_left)
@@ -320,7 +348,7 @@ comparison_pre_block(nir_block *block, struct block_queue 
*bq, nir_builder *bld)
          /* If the instruction is a comparison that is used by an if-statement
           * and neither operand is immediate value 0, add it to the set.
           */
-         if (is_used_by_if(alu) &&
+         if (is_compatible_condition(alu) &&
              is_not_const_zero(NULL, alu, 0, 1, swizzle) &&
              is_not_const_zero(NULL, alu, 1, 1, swizzle))
             add_instruction_for_block(bi, alu);

Reply via email to