nir/lower_int64: Fix float16 to int64 conversions.
Currently float16 to int64 conversions don't work correctly, because the "div" variable has an infinite value, since 2^32 isn't representable as a 16-bit float, which causes the result of of rem(x, div) to be NaN for all inputs, leading to an incorrect result. Since no values of magnitude greater than 2^32 are representable as a float16 we don't actually need to do the fdiv/frem operations, the conversion is equivalent to f2u32 with the result padded to 64 bits. Rework: * Jordan: Handle f16 in if/else rather than conditional Fixes:936c58c8fc
("nir: Extend nir_lower_int64() to support i2f/f2i lowering") Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19391> (cherry picked from commite14f85366e
)
This commit is contained in:

committed by
Dylan Baker

parent
dde0dab8b5
commit
ef4460c21c
@@ -463,7 +463,7 @@
|
||||
"description": "nir/lower_int64: Fix float16 to int64 conversions.",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "936c58c8fcceee086d3c492712595555afe82266"
|
||||
},
|
||||
|
@@ -765,10 +765,15 @@ lower_f2(nir_builder *b, nir_ssa_def *x, bool dst_is_signed)
|
||||
if (dst_is_signed)
|
||||
x = nir_fabs(b, x);
|
||||
|
||||
nir_ssa_def *div = nir_imm_floatN_t(b, 1ULL << 32, x->bit_size);
|
||||
nir_ssa_def *res_hi = nir_f2u32(b, nir_fdiv(b, x, div));
|
||||
nir_ssa_def *res_lo = nir_f2u32(b, nir_frem(b, x, div));
|
||||
nir_ssa_def *res = nir_pack_64_2x32_split(b, res_lo, res_hi);
|
||||
nir_ssa_def *res;
|
||||
if (x->bit_size < 32) {
|
||||
res = nir_pack_64_2x32_split(b, nir_f2u32(b, x), nir_imm_int(b, 0));
|
||||
} else {
|
||||
nir_ssa_def *div = nir_imm_floatN_t(b, 1ULL << 32, x->bit_size);
|
||||
nir_ssa_def *res_hi = nir_f2u32(b, nir_fdiv(b, x, div));
|
||||
nir_ssa_def *res_lo = nir_f2u32(b, nir_frem(b, x, div));
|
||||
res = nir_pack_64_2x32_split(b, res_lo, res_hi);
|
||||
}
|
||||
|
||||
if (dst_is_signed)
|
||||
res = nir_bcsel(b, nir_flt(b, x_sign, nir_imm_floatN_t(b, 0, x->bit_size)),
|
||||
|
Reference in New Issue
Block a user