From 766fdeccf943d090694d4fbeebbe470904481d32 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 16 Dec 2019 14:43:53 -0800 Subject: [PATCH] intel/vec4: Fix lowering of multiplication by 16-bit constant Existing code was ignoring whether the type of the immediate source was signed or not. If the source was signed, it would ignore small negative values but it also would wrongly accept values between INT16_MAX and UINT16_MAX, causing the atual value to later be reinterpreted as a negative number (under 16-bits). Fixes tests/shaders/glsl-mul-const.shader_test in Piglit for older platforms that don't support MUL with 32x32 types and use vec4. Cc: Reviewed-by: Jason Ekstrand --- src/intel/compiler/brw_vec4_nir.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/intel/compiler/brw_vec4_nir.cpp b/src/intel/compiler/brw_vec4_nir.cpp index 3036abcb814..416b6514ad1 100644 --- a/src/intel/compiler/brw_vec4_nir.cpp +++ b/src/intel/compiler/brw_vec4_nir.cpp @@ -1109,6 +1109,18 @@ vec4_visitor::fix_float_operands(src_reg op[3], nir_alu_instr *instr) } } +static bool +const_src_fits_in_16_bits(const nir_src &src, brw_reg_type type) +{ + assert(nir_src_is_const(src)); + if (type_is_unsigned_int(type)) { + return nir_src_comp_as_uint(src, 0) <= UINT16_MAX; + } else { + const int64_t c = nir_src_comp_as_int(src, 0); + return c <= INT16_MAX && c >= INT16_MIN; + } +} + void vec4_visitor::nir_emit_alu(nir_alu_instr *instr) { @@ -1217,14 +1229,14 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr) */ if (nir_src_is_const(instr->src[0].src) && nir_alu_instr_src_read_mask(instr, 0) == 1 && - nir_src_comp_as_uint(instr->src[0].src, 0) < (1 << 16)) { + const_src_fits_in_16_bits(instr->src[0].src, op[0].type)) { if (devinfo->gen < 7) emit(MUL(dst, op[0], op[1])); else emit(MUL(dst, op[1], op[0])); } else if (nir_src_is_const(instr->src[1].src) && nir_alu_instr_src_read_mask(instr, 1) == 1 && - nir_src_comp_as_uint(instr->src[1].src, 0) < (1 << 16)) { + const_src_fits_in_16_bits(instr->src[1].src, op[1].type)) { if (devinfo->gen < 7) emit(MUL(dst, op[1], op[0])); else