nir/lower_int64: respect rounding mode when casting to float

Appendix A: Vulkan environemtn for SPIR-V says:
  Operations described as “correctly rounded” will return the infinitely
  precise result, x, rounded so as to be representable in
  floating-point. The rounding mode is not specified, unless the entry
  point is declared with the RoundingModeRTE or the RoundingModeRTZ
  Execution Mode.

Conversion between types are classified as correctly rounded, so let's
do rounding correctly.

v2: check rounding mode for destination bit size (Georg)

Fixes upcoming Vulkan CTS tests:
dEQP-VK.spirv_assembly.instruction.compute.float_controls.fp32.input_args.rounding_rtz_conv_from_uint64_up
dEQP-VK.spirv_assembly.instruction.compute.float_controls.fp32.input_args.rounding_rtz_conv_from_int64_up
dEQP-VK.spirv_assembly.instruction.graphics.float_controls.fp32.input_args.rounding_rtz_conv_from_uint64_up_vert
dEQP-VK.spirv_assembly.instruction.graphics.float_controls.fp32.input_args.rounding_rtz_conv_from_int64_up_vert
dEQP-VK.spirv_assembly.instruction.graphics.float_controls.fp32.input_args.rounding_rtz_conv_from_uint64_up_frag
dEQP-VK.spirv_assembly.instruction.graphics.float_controls.fp32.input_args.rounding_rtz_conv_from_int64_up_frag

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25281>
This commit is contained in:
Iván Briano 2023-09-14 12:15:20 -07:00 committed by Marge Bot
parent 919f5468eb
commit c8a8b09c15

View file

@ -775,11 +775,14 @@ lower_2f(nir_builder *b, nir_def *x, unsigned dest_bit_size,
COND_LOWER_OP(b, iand, x, lsb_mask));
nir_def *round_up = nir_ior(b, COND_LOWER_CMP(b, ilt, half, rem),
nir_iand(b, halfway, is_odd));
if (significand_bits >= 32)
significand = COND_LOWER_OP(b, iadd, significand,
COND_LOWER_CAST(b, b2i64, round_up));
else
significand = nir_iadd(b, significand, nir_b2i32(b, round_up));
if (!nir_is_rounding_mode_rtz(b->shader->info.float_controls_execution_mode,
dest_bit_size)) {
if (significand_bits >= 32)
significand = COND_LOWER_OP(b, iadd, significand,
COND_LOWER_CAST(b, b2i64, round_up));
else
significand = nir_iadd(b, significand, nir_b2i32(b, round_up));
}
nir_def *res;