clc: force exact! across libclc

libclc seems to have piles of bugs where it relies on precise floating point
behaviours to meet CL precision requirements but doesn't actually disable fast
math in its own spir-v. I am tired of playing this whack-a-mole game. Let's just
assume that the math in CLC is right and should not be optimized in unsafe ways,
and force the exact bit across libclc. This works around a large class of libclc
bugs that keep cropping up from innocuous NIR changes.

This does not force the exact bit for application shaders using libclc, just for
the calculations inside of libclc itself. This seems like the right tradeoff all
considered, anything "fast" bypasses libclc anyway.

Fixes generated_tests/cl/builtin/math/builtin-float-pow-1.0.generated.cl on
drivers using nir_opt_reassociate, and probably other stuff.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36527>
This commit is contained in:
Alyssa Rosenzweig
2025-08-01 15:35:24 -04:00
committed by Marge Bot
parent cfd5fbfde1
commit aca4948997
+18
View File
@@ -22,6 +22,7 @@
*/
#include "nir.h"
#include "nir_builder.h"
#include "nir_clc_helpers.h"
#include "nir_serialize.h"
#include "nir_spirv.h"
@@ -317,6 +318,13 @@ libclc_add_generic_variants(nir_shader *shader)
return progress;
}
static bool
mark_exact(nir_builder *b, nir_alu_instr *alu, UNUSED void *_)
{
alu->exact = true;
return true;
}
nir_shader *
nir_load_libclc_shader(unsigned ptr_bit_size,
struct disk_cache *disk_cache,
@@ -374,6 +382,16 @@ nir_load_libclc_shader(unsigned ptr_bit_size,
NIR_PASS(_, nir, libclc_add_generic_variants);
/* libclc relies on precise floating point behaviour to meet CL precision
* requirements, but the SPIR-V does not disable contractions etc. Forcing
* the exact bit across libclc effectively compiles libclc without fast-math,
* which works around a large class of (current and future) libclc bugs.
*
* Kernels using CL are unaffected, this only affects the high-precision
* floating point routines inside libclc. Fast variants bypass libclc anyway.
*/
NIR_PASS(_, nir, nir_shader_alu_pass, mark_exact, nir_metadata_all, NULL);
/* Run some optimization passes. Those used here should be considered safe
* for all use cases and drivers.
*/