From 7cc32b0e1538772bbda92b6468fa3733509034da Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 19 May 2023 03:53:07 -0700 Subject: [PATCH] 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 Part-of: (cherry picked from commit 9293d8e64bc72ac15c075b67f711fa2d986bcafb) --- .pick_status.json | 2 +- src/compiler/nir/nir.h | 1 + src/compiler/nir/nir_lower_int64.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index cb0eeb0b35a..ca056f270e1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -157,7 +157,7 @@ "description": "nir: Add find_lsb lowering to nir_lower_int64.", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, 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 @@ -701,6 +701,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)