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:
Rhys Perry
2021-10-06 15:06:51 +01:00
committed by Marge Bot
parent 07a520f731
commit c23411a970
2 changed files with 33 additions and 6 deletions
+10
View File
@@ -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.
+23 -6
View File
@@ -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,