nir: add opcodes for *find_msb_rev and lowering

Some hardware supports a version of find_msb where the bits are counted
starting at the high bit, and this needs some lowering to obtain the
value that is expected by *find_msb

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Kristian H. Kristensen <hoegsberg@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9452>
This commit is contained in:
Gert Wollny
2021-03-10 09:38:18 +01:00
parent 28d116c889
commit a5747f8ab3
3 changed files with 40 additions and 0 deletions

View File

@@ -3160,6 +3160,8 @@ typedef struct nir_shader_compiler_options {
bool lower_bit_count;
/** Lowers ifind_msb to compare and ufind_msb */
bool lower_ifind_msb;
/** Lowers ifind_msb and ufind_msb to reverse variants */
bool lower_find_msb_to_reverse;
/** Lowers find_lsb to ufind_msb and logic ops */
bool lower_find_lsb;
bool lower_uadd_carry;

View File

@@ -454,6 +454,16 @@ for (int bit = bit_size - 1; bit >= 0; bit--) {
}
""")
unop_convert("ufind_msb_rev", tint32, tuint, """
dst = -1;
for (int bit = 0; bit < bit_size; bit++) {
if ((src0 << bit) & 0x80000000) {
dst = bit;
break;
}
}
""")
unop("uclz", tuint32, """
int bit;
for (bit = bit_size - 1; bit >= 0; bit--) {
@@ -477,6 +487,22 @@ for (int bit = 31; bit >= 0; bit--) {
}
""")
unop_convert("ifind_msb_rev", tint32, tuint, """
dst = -1;
if (src0 != 0 || src0 != -1) {
for (int bit = 0; bit < 31; bit++) {
/* If src0 < 0, we're looking for the first 0 bit.
* if src0 >= 0, we're looking for the first 1 bit.
*/
if ((((src0 << bit) & 0x40000000) && (src0 >= 0)) ||
((!((src0 << bit) & 0x40000000)) && (src0 < 0))) {
dst = bit;
break;
}
}
}
""")
unop_convert("find_lsb", tint32, tint, """
dst = -1;
for (unsigned bit = 0; bit < bit_size; bit++) {

View File

@@ -1523,6 +1523,18 @@ optimizations.extend([
('ufind_msb', ('bcsel', ('ilt', 'value', 0), ('inot', 'value'), 'value')),
'options->lower_ifind_msb'),
(('ifind_msb', 'value'),
('bcsel', ('ige', ('ifind_msb_rev', 'value'), 0),
('isub', 31, ('ifind_msb_rev', 'value')),
('ifind_msb_rev', 'value')),
'options->lower_find_msb_to_reverse'),
(('ufind_msb', 'value'),
('bcsel', ('ige', ('ufind_msb_rev', 'value'), 0),
('isub', 31, ('ufind_msb_rev', 'value')),
('ufind_msb_rev', 'value')),
'options->lower_find_msb_to_reverse'),
(('find_lsb', 'value'),
('ufind_msb', ('iand', 'value', ('ineg', 'value'))),
'options->lower_find_lsb'),