spirv: Produce correct result for GLSLstd450Tanh with NaN

No shader-db or fossil-db changes on any Intel platform.

Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Fixes: 9f9432d56c ("Revert "spirv: Use a simpler and more correct implementaiton of tanh()"")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13999>
(cherry picked from commit 93ed87af28)
This commit is contained in:
Ian Romanick 2021-10-29 10:51:25 -07:00 committed by Eric Engestrom
parent 724acc7bd6
commit 62fc70d62b
2 changed files with 30 additions and 6 deletions

View file

@ -3811,7 +3811,7 @@
"description": "spirv: Produce correct result for GLSLstd450Tanh with NaN",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "9f9432d56c055b9704a76cad44da88d5e12f825c"
},

View file

@ -520,11 +520,35 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
nir_ssa_def *x = nir_fclamp(nb, src[0],
nir_imm_floatN_t(nb, -clamped_x, bit_size),
nir_imm_floatN_t(nb, clamped_x, bit_size));
dest->def =
nir_fdiv(nb, nir_fsub(nb, nir_fexp(nb, x),
nir_fexp(nb, nir_fneg(nb, x))),
nir_fadd(nb, nir_fexp(nb, x),
nir_fexp(nb, nir_fneg(nb, x))));
/* The clamping will filter out NaN values causing an incorrect result.
* The comparison is carefully structured to get NaN result for NaN and
* get -0 for -0.
*
* result = abs(s) > 0.0 ? ... : s;
*/
const bool exact = nb->exact;
nb->exact = true;
nir_ssa_def *is_regular = nir_flt(nb,
nir_imm_floatN_t(nb, 0, bit_size),
nir_fabs(nb, src[0]));
/* The extra 1.0*s ensures that subnormal inputs are flushed to zero
* when that is selected by the shader.
*/
nir_ssa_def *flushed = nir_fmul(nb,
src[0],
nir_imm_floatN_t(nb, 1.0, bit_size));
nb->exact = exact;
dest->def = nir_bcsel(nb,
is_regular,
nir_fdiv(nb, nir_fsub(nb, nir_fexp(nb, x),
nir_fexp(nb, nir_fneg(nb, x))),
nir_fadd(nb, nir_fexp(nb, x),
nir_fexp(nb, nir_fneg(nb, x)))),
flushed);
break;
}