From a78ed8b8e87374aeb8f7deef4b7b83654a17c19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 13 Apr 2025 20:25:01 -0400 Subject: [PATCH] nir: handle extract opcodes recursively in nir_def_bits_used Reviewed-by: Georg Lehmann Part-of: --- src/compiler/nir/nir_range_analysis.c | 28 +++++++++++-------- .../nir/tests/range_analysis_tests.cpp | 4 +++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/compiler/nir/nir_range_analysis.c b/src/compiler/nir/nir_range_analysis.c index 9e5a5c53539..22d3c206a4e 100644 --- a/src/compiler/nir/nir_range_analysis.c +++ b/src/compiler/nir/nir_range_analysis.c @@ -2167,21 +2167,25 @@ ssa_def_bits_used(const nir_def *def, int recur) case nir_op_extract_u8: case nir_op_extract_i8: - if (src_idx == 0 && nir_src_is_const(use_alu->src[1].src)) { - unsigned chunk = nir_src_comp_as_uint(use_alu->src[1].src, - use_alu->src[1].swizzle[0]); - bits_used |= 0xffull << (chunk * 8); - break; - } else { - return all_bits; - } - case nir_op_extract_u16: case nir_op_extract_i16: if (src_idx == 0 && nir_src_is_const(use_alu->src[1].src)) { - unsigned chunk = nir_src_comp_as_uint(use_alu->src[1].src, - use_alu->src[1].swizzle[0]); - bits_used |= 0xffffull << (chunk * 16); + unsigned chunk = nir_alu_src_as_uint(use_alu->src[1]); + uint64_t defs_bits_used = ssa_def_bits_used(&use_alu->def, recur); + unsigned field_bits = use_alu->op == nir_op_extract_u8 || + use_alu->op == nir_op_extract_i8 ? 8 : 16; + uint64_t field_bitmask = BITFIELD64_MASK(field_bits); + + /* If one of the sign-extended bits is used, set the last src bit + * as used. + */ + if ((use_alu->op == nir_op_extract_i8 || + use_alu->op == nir_op_extract_i16) && + defs_bits_used & ~field_bitmask) + defs_bits_used |= BITFIELD64_BIT(field_bits - 1); + + bits_used |= (field_bitmask & defs_bits_used) << + (chunk * field_bits); break; } else { return all_bits; diff --git a/src/compiler/nir/tests/range_analysis_tests.cpp b/src/compiler/nir/tests/range_analysis_tests.cpp index 4a7a591be23..7dbdca3a2ff 100644 --- a/src/compiler/nir/tests/range_analysis_tests.cpp +++ b/src/compiler/nir/tests/range_analysis_tests.cpp @@ -137,6 +137,7 @@ TEST_F(ssa_def_bits_used_test, extract_i16_with_const_index) src1_imm[3]); nir_alu_instr *alu = build_alu_instr(nir_op_extract_i16, src0, src1); + nir_store_global(b, nir_undef(b, 1, 64), 4, &alu->def, 0x1); ASSERT_NE((void *) 0, alu); @@ -168,6 +169,7 @@ TEST_F(ssa_def_bits_used_test, extract_u16_with_const_index) src1_imm[3]); nir_alu_instr *alu = build_alu_instr(nir_op_extract_u16, src0, src1); + nir_store_global(b, nir_undef(b, 1, 64), 4, &alu->def, 0x1); ASSERT_NE((void *) 0, alu); @@ -199,6 +201,7 @@ TEST_F(ssa_def_bits_used_test, extract_i8_with_const_index) src1_imm[3]); nir_alu_instr *alu = build_alu_instr(nir_op_extract_i8, src0, src1); + nir_store_global(b, nir_undef(b, 1, 64), 4, &alu->def, 0x1); ASSERT_NE((void *) 0, alu); @@ -230,6 +233,7 @@ TEST_F(ssa_def_bits_used_test, extract_u8_with_const_index) src1_imm[3]); nir_alu_instr *alu = build_alu_instr(nir_op_extract_u8, src0, src1); + nir_store_global(b, nir_undef(b, 1, 64), 4, &alu->def, 0x1); ASSERT_NE((void *) 0, alu);