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 <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18006>
This commit is contained in:
Ian Romanick 2022-09-06 10:28:14 -07:00 committed by Marge Bot
parent 61c3438b27
commit 5473536798

View file

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