nir: handle ibfe/ubfe in nir_def_bits_used

it will be used by radeonsi

Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34489>
This commit is contained in:
Marek Olšák 2025-04-10 20:47:23 -04:00 committed by Marge Bot
parent 81bdf1ace6
commit 7d24a9b649
2 changed files with 66 additions and 0 deletions

View file

@ -2212,6 +2212,39 @@ ssa_def_bits_used(const nir_def *def, int recur)
return all_bits;
}
case nir_op_ibfe:
case nir_op_ubfe:
if (src_idx == 0 && nir_src_is_const(use_alu->src[1].src)) {
uint64_t def_bits_used = ssa_def_bits_used(&use_alu->def, recur);
unsigned bit_size = use_alu->def.bit_size;
unsigned offset = nir_alu_src_as_uint(use_alu->src[1]) & (bit_size - 1);
unsigned bits = nir_src_is_const(use_alu->src[2].src) ?
nir_alu_src_as_uint(use_alu->src[2]) & (bit_size - 1) :
/* Worst case if bits is not constant. */
(bit_size - offset);
uint64_t field_bitmask = BITFIELD64_MASK(bits);
/* If one of the sign-extended bits is used, set the last src
* bit as used.
* If bits is not constant, all bits can be the last one.
*/
if (use_alu->op == nir_op_ibfe &&
(def_bits_used >> offset) & ~field_bitmask) {
if (nir_alu_src_as_uint(use_alu->src[2]))
def_bits_used |= BITFIELD64_BIT(bits - 1);
else
def_bits_used |= field_bitmask;
}
bits_used |= (field_bitmask & def_bits_used) << offset;
break;
} else if (src_idx == 1 || src_idx == 2) {
bits_used |= use_alu->src[0].src.ssa->bit_size - 1;
break;
} else {
return all_bits;
}
default:
/* We don't know what this op does */
return all_bits;

View file

@ -291,3 +291,36 @@ TEST_F(unsigned_upper_bound_test, loop_phi_bcsel)
EXPECT_EQ(nir_unsigned_upper_bound(b->shader, range_ht, scalar, NULL), 2);
_mesa_hash_table_destroy(range_ht, NULL);
}
TEST_F(ssa_def_bits_used_test, ubfe_ibfe)
{
nir_def *load1 = nir_load_global(b, nir_undef(b, 1, 64), 4, 1, 32);
nir_def *load2 = nir_load_global(b, nir_undef(b, 1, 64), 4, 1, 32);
nir_def *alu1 = nir_ubfe_imm(b, load1, 14, 3);
nir_def *alu2 = nir_ibfe_imm(b, load2, 12, 7);
nir_store_global(b, nir_undef(b, 1, 64), 4, alu1, 0x1);
nir_store_global(b, nir_undef(b, 1, 64), 4, alu2, 0x1);
EXPECT_EQ(nir_def_bits_used(load1), BITFIELD_RANGE(14, 3));
EXPECT_EQ(nir_def_bits_used(load2), BITFIELD_RANGE(12, 7));
}
TEST_F(ssa_def_bits_used_test, ibfe_iand)
{
nir_def *load = nir_load_global(b, nir_undef(b, 1, 64), 4, 1, 32);
nir_def *alu = nir_iand_imm(b, nir_ibfe_imm(b, load, 14, 3), 0x80000000);
nir_store_global(b, nir_undef(b, 1, 64), 4, alu, 0x1);
EXPECT_EQ(nir_def_bits_used(load), BITFIELD_BIT(16));
}
TEST_F(ssa_def_bits_used_test, ubfe_iand)
{
nir_def *load = nir_load_global(b, nir_undef(b, 1, 64), 4, 1, 32);
nir_def *alu = nir_iand_imm(b, nir_ubfe_imm(b, load, 14, 3), 0x2);
nir_store_global(b, nir_undef(b, 1, 64), 4, alu, 0x1);
EXPECT_EQ(nir_def_bits_used(load), BITFIELD_BIT(15));
}