nir/algebraic: Simplify various trivial bfi

These are mostly just obvious patterns that somebody will eventually
want to add.

DG2, Tiger Lake, Ice Lake, Skylake, Broadwell, and Haswell had similar
results (Ice Lake shown)
total instructions in shared programs: 20570033 -> 20570026 (<.01%)
instructions in affected programs: 7363 -> 7356 (-0.10%)
helped: 6 / HURT: 0

total cycles in shared programs: 902118781 -> 902118854 (<.01%)
cycles in affected programs: 419132 -> 419205 (0.02%)
helped: 4 / HURT: 2

DG2, Tiger Lake, Ice Lake, and Skylake had similar results (Ice Lake shown)
Totals:
Instrs: 152819500 -> 152819380 (-0.00%)
Cycles: 15014627187 -> 15014624437 (-0.00%)

Totals from 115 (0.02% of 662497) affected shaders:
Instrs: 28963 -> 28843 (-0.41%)
Cycles: 404582 -> 401832 (-0.68%)

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19968>
This commit is contained in:
Ian Romanick 2020-03-31 15:37:00 -07:00 committed by Marge Bot
parent 541e7eb389
commit de60b463d7
2 changed files with 50 additions and 0 deletions

View file

@ -1386,6 +1386,27 @@ optimizations.extend([
(('uror@32', a, b), ('ior', ('ushr', a, b), ('ishl', a, ('isub', 32, b))), 'options->lower_rotate'),
(('uror@64', a, b), ('ior', ('ushr', a, b), ('ishl', a, ('isub', 64, b))), 'options->lower_rotate'),
# bfi(X, a, b) = (b & ~X) | (a & X)
# If X = ~0: (b & 0) | (a & 0xffffffff) = a
# If X = 0: (b & 0xffffffff) | (a & 0) = b
(('bfi', 0xffffffff, a, b), a),
(('bfi', 0x00000000, a, b), b),
# The result of -int(some_bool) is 0 or 0xffffffff, so the result of the
# bfi is either b or c.
(('bfi', ('ineg', ('b2i', 'a@1')), b, c), ('bcsel', a, b, c)),
# bfi(a, a, b) = ((a << find_lsb(a)) & a) | (b & ~a)
# = (a & a) | (b & ~a) If a is odd, find_lsb(a) == 0
# = a | (b & ~a)
# = a | b
(('bfi', '#a(is_odd)', a, b), ('ior', a, b)),
# bfi(a, b, 0) = ((b << find_lsb(a)) & a) | (0 & ~a)
# = ((b << find_lsb(a)) & a)
# = (b & a) If a is odd, find_lsb(a) == 0
(('bfi', '#a(is_odd)', b, 0), ('iand', a, b)),
# Because 'a' is a positive power of two, the result of the bfi is either 0
# or 'a' depending on whether or not 'b' is odd. Use 'b&1' for the zero
# value to help platforms that can't have two constants in a bcsel.

View file

@ -196,6 +196,35 @@ is_gt_0_and_lt_1(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
return true;
}
/**
* x & 1 != 0
*/
static inline bool
is_odd(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
unsigned src, unsigned num_components,
const uint8_t *swizzle)
{
/* only constant srcs: */
if (!nir_src_is_const(instr->src[src].src))
return false;
for (unsigned i = 0; i < num_components; i++) {
nir_alu_type type = nir_op_infos[instr->op].input_types[src];
switch (nir_alu_type_get_base_type(type)) {
case nir_type_int:
case nir_type_uint: {
if ((nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) & 1) == 0)
return false;
break;
}
default:
return false;
}
}
return true;
}
static inline bool
is_not_const_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
unsigned src, unsigned num_components,