diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2023-05-19 03:53:07 -0700 |
---|---|---|
committer | Eric Engestrom <eric@engestrom.ch> | 2023-05-25 14:06:12 +0100 |
commit | 7cc32b0e1538772bbda92b6468fa3733509034da (patch) | |
tree | 99cb8c127a35f0500e72b539f1aed89c9c0d72f4 /src/compiler | |
parent | 1b4720b30599e24492b18480be531dcd5ccd48bd (diff) | |
download | mesa-7cc32b0e1538772bbda92b6468fa3733509034da.tar.gz mesa-7cc32b0e1538772bbda92b6468fa3733509034da.tar.bz2 mesa-7cc32b0e1538772bbda92b6468fa3733509034da.zip |
nir: Add find_lsb lowering to nir_lower_int64.
Some GPUs can only handle 32-bit find_lsb.
Cc: mesa-stable
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23123>
(cherry picked from commit 9293d8e64bc72ac15c075b67f711fa2d986bcafb)
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir.h | 1 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_int64.c | 19 |
2 files changed, 20 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 4c3fa21651a..4b4d6cc64ac 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3352,6 +3352,7 @@ typedef enum { nir_lower_vote_ieq64 = (1 << 19), nir_lower_usub_sat64 = (1 << 20), nir_lower_iadd_sat64 = (1 << 21), + nir_lower_find_lsb64 = (1 << 22), } nir_lower_int64_options; typedef enum { diff --git a/src/compiler/nir/nir_lower_int64.c b/src/compiler/nir/nir_lower_int64.c index eb1dc1e3409..c3e541e2228 100644 --- a/src/compiler/nir/nir_lower_int64.c +++ b/src/compiler/nir/nir_lower_int64.c @@ -702,6 +702,20 @@ lower_ufind_msb64(nir_builder *b, nir_ssa_def *x) } static nir_ssa_def * +lower_find_lsb64(nir_builder *b, nir_ssa_def *x) +{ + nir_ssa_def *x_lo = nir_unpack_64_2x32_split_x(b, x); + nir_ssa_def *x_hi = nir_unpack_64_2x32_split_y(b, x); + nir_ssa_def *lo_lsb = nir_find_lsb(b, x_lo); + nir_ssa_def *hi_lsb = nir_find_lsb(b, x_hi); + + /* Use umin so that -1 (no bits found) becomes larger (0xFFFFFFFF) + * than any actual bit position, so we return a found bit instead. + */ + return nir_umin(b, lo_lsb, nir_iadd(b, hi_lsb, nir_imm_int(b, 32))); +} + +static nir_ssa_def * lower_2f(nir_builder *b, nir_ssa_def *x, unsigned dest_bit_size, bool src_is_signed) { @@ -932,6 +946,8 @@ nir_lower_int64_op_to_options_mask(nir_op opcode) return nir_lower_extract64; case nir_op_ufind_msb: return nir_lower_ufind_msb64; + case nir_op_find_lsb: + return nir_lower_find_lsb64; case nir_op_bit_count: return nir_lower_bit_count64; default: @@ -1034,6 +1050,8 @@ lower_int64_alu_instr(nir_builder *b, nir_alu_instr *alu) return lower_extract(b, alu->op, src[0], src[1]); case nir_op_ufind_msb: return lower_ufind_msb64(b, src[0]); + case nir_op_find_lsb: + return lower_find_lsb64(b, src[0]); case nir_op_bit_count: return lower_bit_count64(b, src[0]); case nir_op_i2f64: @@ -1089,6 +1107,7 @@ should_lower_int64_alu_instr(const nir_alu_instr *alu, return false; break; case nir_op_ufind_msb: + case nir_op_find_lsb: case nir_op_bit_count: assert(alu->src[0].src.is_ssa); if (alu->src[0].src.ssa->bit_size != 64) |