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);
