summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2020-08-12 15:50:07 -0700
committerIan Romanick <ian.d.romanick@intel.com>2021-04-02 12:56:18 -0700
commit18a9d3f17ebea940e366d2b38a6c9424e6f65f58 (patch)
tree46efe39522a977c08864314fa82b91af8032f44e
parent0e6d85407cf5b5c857a90a9b1406a7d1b4098e21 (diff)
nir/range_analysis: Range tracking for flog2
No shader-db or fossil-db changes on any Intel platform.
-rw-r--r--src/compiler/nir/nir_range_analysis.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_range_analysis.c b/src/compiler/nir/nir_range_analysis.c
index dd658400b29..96458ea94a5 100644
--- a/src/compiler/nir/nir_range_analysis.c
+++ b/src/compiler/nir/nir_range_analysis.c
@@ -850,6 +850,62 @@ analyze_expression(const nir_alu_instr *instr, unsigned src,
break;
}
+ case nir_op_flog2: {
+ const struct ssa_result_range right =
+ analyze_expression(alu, 0, ht, nir_alu_src_type(alu, 0));
+
+ if (alu->src[0].src.is_ssa &&
+ alu->src[0].src.ssa->parent_instr->type == nir_instr_type_alu) {
+ const struct nir_alu_instr *const src_alu =
+ nir_instr_as_alu(alu->src[0].src.ssa->parent_instr);
+
+ /* On the domain [0,1), logarithm is always negative, and the
+ * logarithm of 1.0 is 0.0.
+ */
+ if (src_alu->op == nir_op_fsat)
+ r.range = le_zero;
+ }
+
+ /* Logarithm is defined for the domain (0, +Inf]. Section 8.2
+ * (Exponential Functions) of the GLSL 4.60 spec says (for log2):
+ *
+ * Results are undefined if x <= 0.
+ *
+ * Depending on the underlying GPU, undefined may mean NaN.
+ *
+ * IEEE 754 has a somewhat tighter requirement for log2. From
+ * https://pubs.opengroup.org/onlinepubs/9699919799.2016edition/functions/log.html
+ *
+ * If x is ±0, a pole error shall occur and log(), logf(), and logl()
+ * shall return -HUGE_VAL, -HUGE_VALF, and -HUGE_VALL, respectively.
+ *
+ * For finite values of x that are less than 0, or if x is -Inf,
+ * 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 1, +0 shall be returned.
+ *
+ * If x is +Inf, x shall be returned.
+ *
+ * HLSL documentation says:
+ *
+ * If the x parameter is 0, this function returns +INF.
+ *
+ * For GPUs that follow the IEEE requirements for x=0, the condition
+ * could be changed to include ge_zero and eq_zero.
+ */
+ r.is_a_number = right.is_a_number && right.range == gt_zero;
+
+ /* This may be sketchy. Is there any way to be sure a GPU won't return
+ * -Inf for log2(epsilon)? It would violate IEEE 754, but GLSL, SPIR-V,
+ * and HLSL are silent on the topic.
+ */
+ r.is_finite = r.is_a_number && right.is_finite;
+ break;
+ }
+
case nir_op_fmax: {
const struct ssa_result_range left =
analyze_expression(alu, 0, ht, nir_alu_src_type(alu, 0));