Module: Mesa Branch: main Commit: c23411a970144a51b3ddffb1e97d46bb3b3ca362 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c23411a970144a51b3ddffb1e97d46bb3b3ca362
Author: Rhys Perry <[email protected]> Date: Wed Oct 6 15:06:51 2021 +0100 nir/algebraic: optimize bits=umin(bits, 32-(offset&0x1f)) Optimizes patterns which are created by recent versions of vkd3d-proton, when constant folding doesn't eliminate it entirely: - ubitfield_extract(value, offset, umin(bits, 32-(offset&0x1f))) - ibitfield_extract(value, offset, umin(bits, 32-(offset&0x1f))) - bitfield_insert(base, insert, offset, umin(bits, 32-(offset&0x1f))) Signed-off-by: Rhys Perry <[email protected]> Reviewed-by: Timur Kristóf <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13225> --- src/compiler/nir/nir_opt_algebraic.py | 10 ++++++++++ src/compiler/nir/nir_search_helpers.h | 29 +++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 2930715e01d..34eec399ef1 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -1813,6 +1813,16 @@ optimizations.extend([ (('bfm', 'bits', ('iand', 31, 'offset')), ('bfm', 'bits', 'offset')), (('bfm', ('iand', 31, 'bits'), 'offset'), ('bfm', 'bits', 'offset')), + # Optimizations for ubitfield_extract(value, offset, umin(bits, 32-(offset&0x1f))) and such + (('ult', a, ('umin', ('iand', a, b), c)), False), + (('ult', 31, ('umin', '#bits(is_ult_32)', a)), False), + (('ubfe', 'value', 'offset', ('umin', 'width', ('iadd', 32, ('ineg', ('iand', 31, 'offset'))))), + ('ubfe', 'value', 'offset', 'width')), + (('ibfe', 'value', 'offset', ('umin', 'width', ('iadd', 32, ('ineg', ('iand', 31, 'offset'))))), + ('ibfe', 'value', 'offset', 'width')), + (('bfm', ('umin', 'width', ('iadd', 32, ('ineg', ('iand', 31, 'offset')))), 'offset'), + ('bfm', 'width', 'offset')), + # Section 8.8 (Integer Functions) of the GLSL 4.60 spec says: # # If bits is zero, the result will be zero. diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h index 82caa439b15..60a349baca0 100644 --- a/src/compiler/nir/nir_search_helpers.h +++ b/src/compiler/nir/nir_search_helpers.h @@ -225,27 +225,44 @@ is_not_const_zero(UNUSED struct hash_table *ht, const nir_alu_instr *instr, return true; } -/** Is value unsigned less than 0xfffc07fc? */ +/** Is value unsigned less than the limit? */ static inline bool -is_ult_0xfffc07fc(UNUSED struct hash_table *ht, const nir_alu_instr *instr, - unsigned src, unsigned num_components, - const uint8_t *swizzle) +is_ult(const nir_alu_instr *instr, unsigned src, unsigned num_components, const uint8_t *swizzle, + uint64_t limit) { /* only constant srcs: */ if (!nir_src_is_const(instr->src[src].src)) return false; for (unsigned i = 0; i < num_components; i++) { - const unsigned val = + const uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]); - if (val >= 0xfffc07fcU) + if (val >= limit) return false; } return true; } +/** Is value unsigned less than 32? */ +static inline bool +is_ult_32(UNUSED struct hash_table *ht, const nir_alu_instr *instr, + unsigned src, unsigned num_components, + const uint8_t *swizzle) +{ + return is_ult(instr, src, num_components, swizzle, 32); +} + +/** Is value unsigned less than 0xfffc07fc? */ +static inline bool +is_ult_0xfffc07fc(UNUSED struct hash_table *ht, const nir_alu_instr *instr, + unsigned src, unsigned num_components, + const uint8_t *swizzle) +{ + return is_ult(instr, src, num_components, swizzle, 0xfffc07fcU); +} + /** Is the first 5 bits of value unsigned greater than or equal 2? */ static inline bool is_first_5_bits_uge_2(UNUSED struct hash_table *ht, const nir_alu_instr *instr,
