diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2020-07-02 18:52:39 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2021-04-02 12:56:18 -0700 |
commit | 8eae15f73d367efe2937bf54da99086d5782bcc8 (patch) | |
tree | 87a6eea8d252af5abd488cc74548cf790e135108 | |
parent | 18a9d3f17ebea940e366d2b38a6c9424e6f65f58 (diff) |
nir/range_analysis: Improve "is a number" range analysis for fsqrt and frsq
No shader-db or fossil-db changes on any Intel platform.
-rw-r--r-- | src/compiler/nir/nir_range_analysis.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/compiler/nir/nir_range_analysis.c b/src/compiler/nir/nir_range_analysis.c index 96458ea94a5..7fa6d5f7ebd 100644 --- a/src/compiler/nir/nir_range_analysis.c +++ b/src/compiler/nir/nir_range_analysis.c @@ -1152,9 +1152,42 @@ analyze_expression(const nir_alu_instr *instr, unsigned src, break; case nir_op_fsqrt: - case nir_op_frsq: + case nir_op_frsq: { r = (struct ssa_result_range){ge_zero, false, false, false}; + + const struct ssa_result_range left = + analyze_expression(alu, 0, ht, nir_alu_src_type(alu, 0)); + + /* Section 8.2 (Exponential Functions) of the GLSL 4.60 spec says (for + * sqrt): + * + * Results are undefined if x < 0. + * + * It also says (for inversesqrt): + * + * Results are undefined if x <= 0. + * + * IEEE 754 has a somewhat tighter requirement for sqrt. From + * https://pubs.opengroup.org/onlinepubs/9699919799.2016edition/functions/sqrt.html + * + * For finite values of x < -0, a domain error shall occur, and + * either a NaN (if supported), or an implementation-defined value + * shall be returned. + * + * If x is NaN, a NaN shall be returned. + * + * If x is ±0 or +Inf, x shall be returned. + * + * If x is -Inf, a domain error shall occur, and a NaN shall be + * returned + * + * For inversesqrt, treat the "is a number" result as though it were + * from 1.0 / sqrt(x). 1.0/±0 is ±Inf. For this purpose, that is a + * number. + */ + r.is_a_number = left.is_a_number && is_not_negative(left.range); break; + } case nir_op_ffloor: { const struct ssa_result_range left = |