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 <pendingchaos02@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13225>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user