nir/opt_algebraic: create ubfe from (a & mask) >> c
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Foz-DB Navi21:
Totals from 917 (1.16% of 79188) affected shaders:
Instrs: 2549482 -> 2544997 (-0.18%); split: -0.18%, +0.00%
CodeSize: 13781648 -> 13763616 (-0.13%); split: -0.13%, +0.00%
Latency: 24832087 -> 24825199 (-0.03%); split: -0.04%, +0.01%
InvThroughput: 5921339 -> 5914799 (-0.11%); split: -0.12%, +0.01%
VClause: 59910 -> 59898 (-0.02%); split: -0.02%, +0.00%
SClause: 62294 -> 62293 (-0.00%)
Copies: 221015 -> 220988 (-0.01%); split: -0.02%, +0.01%
VALU: 1717280 -> 1713332 (-0.23%); split: -0.23%, +0.00%
SALU: 359390 -> 358910 (-0.13%)
VMEM: 101966 -> 101924 (-0.04%)

Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33455>
This commit is contained in:
Georg Lehmann 2025-02-08 17:02:46 +01:00 committed by Marge Bot
parent b2a2d197f9
commit b386659588
2 changed files with 30 additions and 0 deletions

View file

@ -595,6 +595,12 @@ optimizations.extend([
(('ushr', ('iand', a, ('bfm', c, b)), b),
('ubfe', a, b, c), 'options->has_bfe'),
(('ushr@32', ('iand(is_used_once)', a, '#b(is_const_bfm)'), '#c'),
('bcsel', ('ilt', ('find_lsb', b), ('iand', c, 0x1f)),
('ushr', ('ubfe', a, ('find_lsb', b), ('bit_count', b)), ('isub', c, ('find_lsb', b))),
('ishl', ('ubfe', a, ('find_lsb', b), ('bit_count', b)), ('isub', ('find_lsb', b), c))),
'options->has_bfe && !options->avoid_ternary_with_two_constants'),
# Collapse two bitfield extracts with constant operands into a single one.
(('ubfe', ('ubfe', a, '#b', '#c'), '#d', '#e'),
ubfe_ubfe(a, b, c, d, e)),

View file

@ -809,6 +809,30 @@ is_const_bitmask(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
return true;
}
/**
* Returns whether an operand is a non zero constant
* that can be created by nir_op_bfm.
*/
static inline bool
is_const_bfm(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
unsigned src, unsigned num_components,
const uint8_t *swizzle)
{
if (nir_src_as_const_value(instr->src[src].src) == NULL)
return false;
for (unsigned i = 0; i < num_components; i++) {
const unsigned bit_size = instr->src[src].src.ssa->bit_size;
const uint64_t c = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
const unsigned num_bits = util_bitcount64(c);
const unsigned offset = ffsll(c) - 1;
if (c == 0 || c != (BITFIELD64_MASK(num_bits) << offset) || num_bits == bit_size)
return false;
}
return true;
}
/**
* Returns whether the 5 LSBs of an operand are non-zero.
*/