summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2020-07-02 18:52:39 -0700
committerIan Romanick <ian.d.romanick@intel.com>2021-04-02 12:56:18 -0700
commit8eae15f73d367efe2937bf54da99086d5782bcc8 (patch)
tree87a6eea8d252af5abd488cc74548cf790e135108
parent18a9d3f17ebea940e366d2b38a6c9424e6f65f58 (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.c35
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 =