diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2020-08-12 15:50:07 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2021-04-02 12:56:18 -0700 |
commit | 18a9d3f17ebea940e366d2b38a6c9424e6f65f58 (patch) | |
tree | 46efe39522a977c08864314fa82b91af8032f44e | |
parent | 0e6d85407cf5b5c857a90a9b1406a7d1b4098e21 (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.c | 56 |
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)); |