summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2021-10-28 17:34:56 -0700
committerDylan Baker <dylan.c.baker@intel.com>2022-02-24 14:56:50 -0800
commit1830da60e8d2eb753538e0ec733f02857e607450 (patch)
tree070506dbeb200682fff09d83faf0c391b7e8fb5f
parentea3afa5690953c09467d3f56c429deadc2bbcd47 (diff)
nir: Properly handle various exceptional values in frexp
frexp_sig of ±0, ±Inf, or NaN should just return the input unmodified. frexp_exp of ±Inf or NaN is undefined, and frexp_exp of ±0 should return the input unmodified. This seems to already work. No shader-db or fossil-db changes on any Intel platform. Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> Fixes: 23d30f4099f ("spirv,nir: lower frexp_exp/frexp_sig inside a new NIR pass") Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13999> (cherry picked from commit 7d0d9b9fbc231c2bd66778e0b0a62d5c514c5495)
-rw-r--r--.pick_status.json2
-rw-r--r--src/compiler/nir/nir_lower_frexp.c24
2 files changed, 19 insertions, 7 deletions
diff --git a/.pick_status.json b/.pick_status.json
index cbe646789fe..86036c1f6e0 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -85,7 +85,7 @@
"description": "nir: Properly handle various exceptional values in frexp",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "23d30f4099fac0e1fcbd7adf315a186f553e48d2"
},
diff --git a/src/compiler/nir/nir_lower_frexp.c b/src/compiler/nir/nir_lower_frexp.c
index d4be828afdd..f270a18c4fb 100644
--- a/src/compiler/nir/nir_lower_frexp.c
+++ b/src/compiler/nir/nir_lower_frexp.c
@@ -35,7 +35,6 @@ lower_frexp_sig(nir_builder *b, nir_ssa_def *x)
nir_ssa_def *abs_x = nir_fabs(b, x);
nir_ssa_def *zero = nir_imm_floatN_t(b, 0, x->bit_size);
nir_ssa_def *sign_mantissa_mask, *exponent_value;
- nir_ssa_def *is_not_zero = nir_fneu(b, abs_x, zero);
switch (x->bit_size) {
case 16:
@@ -89,18 +88,31 @@ lower_frexp_sig(nir_builder *b, nir_ssa_def *x)
* 32 bits using nir_unpack_64_2x32_split_y.
*/
nir_ssa_def *upper_x = nir_unpack_64_2x32_split_y(b, x);
- nir_ssa_def *zero32 = nir_imm_int(b, 0);
+ /* If x is ±0, ±Inf, or NaN, return x unmodified. */
nir_ssa_def *new_upper =
- nir_ior(b, nir_iand(b, upper_x, sign_mantissa_mask),
- nir_bcsel(b, is_not_zero, exponent_value, zero32));
+ nir_bcsel(b,
+ nir_iand(b,
+ nir_flt(b, zero, abs_x),
+ nir_fisfinite(b, x)),
+ nir_ior(b,
+ nir_iand(b, upper_x, sign_mantissa_mask),
+ exponent_value),
+ upper_x);
nir_ssa_def *lower_x = nir_unpack_64_2x32_split_x(b, x);
return nir_pack_64_2x32_split(b, lower_x, new_upper);
} else {
- return nir_ior(b, nir_iand(b, x, sign_mantissa_mask),
- nir_bcsel(b, is_not_zero, exponent_value, zero));
+ /* If x is ±0, ±Inf, or NaN, return x unmodified. */
+ return nir_bcsel(b,
+ nir_iand(b,
+ nir_flt(b, zero, abs_x),
+ nir_fisfinite(b, x)),
+ nir_ior(b,
+ nir_iand(b, x, sign_mantissa_mask),
+ exponent_value),
+ x);
}
}