From 33ad2bab4bcb52c0f6be56e2f9cce5f52601a4ea Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 7 Aug 2019 08:56:22 -0700 Subject: [PATCH] nir/range-analysis: Adjust result range of exp2 to account for flush-to-zero MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixes piglit tests (new in piglit!110): - fs-underflow-exp2-compare-zero.shader_test Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111308 Fixes: 405de7ccb6c ("nir/range-analysis: Rudimentary value range analysis pass") Reviewed-by: Caio Marcelo de Oliveira Filho Most of the shaders affected are, unsurprisingly, in Unigine Heaven. All Gen6+ platforms had similar results. (Ice Lake shown) total instructions in shared programs: 16278207 -> 16278465 (<.01%) instructions in affected programs: 11374 -> 11632 (2.27%) helped: 0 HURT: 58 HURT stats (abs) min: 2 max: 13 x̄: 4.45 x̃: 4 HURT stats (rel) min: 0.54% max: 4.11% x̄: 2.42% x̃: 2.82% 95% mean confidence interval for instructions value: 3.77 5.13 95% mean confidence interval for instructions %-change: 2.19% 2.64% Instructions are HURT. total cycles in shared programs: 367134284 -> 367135159 (<.01%) cycles in affected programs: 81207 -> 82082 (1.08%) helped: 17 HURT: 36 helped stats (abs) min: 6 max: 356 x̄: 90.35 x̃: 6 helped stats (rel) min: 0.69% max: 21.45% x̄: 5.71% x̃: 0.78% HURT stats (abs) min: 4 max: 235 x̄: 66.97 x̃: 16 HURT stats (rel) min: 0.35% max: 27.58% x̄: 5.34% x̃: 1.09% 95% mean confidence interval for cycles value: -20.36 53.38 95% mean confidence interval for cycles %-change: -1.08% 4.67% Inconclusive result (value mean confidence interval includes 0). No changes on any earlier platforms. --- src/compiler/nir/nir_range_analysis.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_range_analysis.c b/src/compiler/nir/nir_range_analysis.c index f9756ef080c..3acaa4774ae 100644 --- a/src/compiler/nir/nir_range_analysis.c +++ b/src/compiler/nir/nir_range_analysis.c @@ -453,9 +453,21 @@ analyze_expression(const nir_alu_instr *instr, unsigned src, break; } - case nir_op_fexp2: - r = (struct ssa_result_range){gt_zero, analyze_expression(alu, 0, ht).is_integral}; + case nir_op_fexp2: { + /* If the parameter might be less than zero, the mathematically result + * will be on (0, 1). For sufficiently large magnitude negative + * parameters, the result will flush to zero. + */ + static const enum ssa_ranges table[last_range + 1] = { + /* unknown lt_zero le_zero gt_zero ge_zero ne_zero eq_zero */ + ge_zero, ge_zero, ge_zero, gt_zero, gt_zero, ge_zero, gt_zero + }; + + r = analyze_expression(alu, 0, ht); + + r.range = table[r.range]; break; + } case nir_op_fmax: { const struct ssa_result_range left = analyze_expression(alu, 0, ht); -- 2.30.2