nir/lower_bit_size: Support add_sat and sub_sat

Without this, lowered saturating ALU instructions would only clamp to
the range of the new type instead of the range of the old type.

v2: Use nir_iclamp.  Suggested by Jason. Use new
u_{int,uint}N_{min,max}() helpers.

Fixes: 090e282407 ("nir: Add a saturated unsigned integer add opcode")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12142>
This commit is contained in:
Ian Romanick 2021-07-28 18:16:24 -07:00 committed by Marge Bot
parent 8503cab2e0
commit 7d8bf7c167

View file

@ -81,6 +81,23 @@ lower_alu_instr(nir_builder *bld, nir_alu_instr *alu, unsigned bit_size)
lowered_dst = nir_ishr_imm(bld, lowered_dst, dst_bit_size);
} else {
lowered_dst = nir_build_alu_src_arr(bld, op, srcs);
/* The add_sat and sub_sat instructions need to clamp the result to the
* range of the original type.
*/
if (op == nir_op_iadd_sat || op == nir_op_isub_sat) {
const int64_t int_max = u_intN_max(dst_bit_size);
const int64_t int_min = u_intN_min(dst_bit_size);
lowered_dst = nir_iclamp(bld, lowered_dst,
nir_imm_intN_t(bld, int_min, bit_size),
nir_imm_intN_t(bld, int_max, bit_size));
} else if (op == nir_op_uadd_sat || op == nir_op_usub_sat) {
const uint64_t uint_max = u_uintN_max(dst_bit_size);
lowered_dst = nir_umin(bld, lowered_dst,
nir_imm_intN_t(bld, uint_max, bit_size));
}
}