Mesa (staging/22.0): nir: Produce correct results for atan with NaN

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Feb 10 21:09:39 UTC 2022


Module: Mesa
Branch: staging/22.0
Commit: b8dc56f5f81b348a0fbd29d74a167021e6fd44b5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8dc56f5f81b348a0fbd29d74a167021e6fd44b5

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Oct 29 10:50:55 2021 -0700

nir: Produce correct results for atan with NaN

Properly handling NaN adversely affects several hundred shaders in
shader-db (lots of Skia and a few others from various synthetic
benchmarks) and fossil-db (mostly Talos and some Doom 2016).  Only apply
the NaN handling work-around when the shader demands it.

v2: Add comment explaining the 1.0*y_over_x.  Suggested by Caio.

Reviewed-by: Caio Oliveira <caio.oliveira at intel.com>
Fixes: 2098ae16c8b ("nir/builder: Move nir_atan and nir_atan2 from SPIR-V translator")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13999>
(cherry picked from commit 1cb3d1a6ae027b5045e47ccf7e551bd81fc3cab2)

---

 .pick_status.json                      |  2 +-
 src/compiler/nir/nir_builtin_builder.c | 23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 9276a4fc4ba..5036819c64f 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -76,7 +76,7 @@
         "description": "nir: Produce correct results for atan with NaN",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "2098ae16c8b4e64d0694a28f74a461b69b98a336"
     },
diff --git a/src/compiler/nir/nir_builtin_builder.c b/src/compiler/nir/nir_builtin_builder.c
index da332e72de9..b975157cfb1 100644
--- a/src/compiler/nir/nir_builtin_builder.c
+++ b/src/compiler/nir/nir_builtin_builder.c
@@ -223,7 +223,28 @@ nir_atan(nir_builder *b, nir_ssa_def *y_over_x)
                   tmp);
 
    /* sign fixup */
-   return nir_fmul(b, tmp, nir_fsign(b, y_over_x));
+   nir_ssa_def *result = nir_fmul(b, tmp, nir_fsign(b, y_over_x));
+
+   /* The fmin and fmax above will filter out NaN values.  This leads to
+    * non-NaN results for NaN inputs.  Work around this by doing
+    *
+    *    !isnan(y_over_x) ? ... : y_over_x;
+    */
+   if (b->exact ||
+       nir_is_float_control_signed_zero_inf_nan_preserve(b->shader->info.float_controls_execution_mode, bit_size)) {
+      const bool exact = b->exact;
+
+      b->exact = true;
+      nir_ssa_def *is_not_nan = nir_feq(b, y_over_x, y_over_x);
+      b->exact = exact;
+
+      /* The extra 1.0*y_over_x ensures that subnormal results are flushed to
+       * zero.
+       */
+      result = nir_bcsel(b, is_not_nan, result, nir_fmul_imm(b, y_over_x, 1.0));
+   }
+
+   return result;
 }
 
 nir_ssa_def *



More information about the mesa-commit mailing list