From aca4948997eb2b9d7d3279e1dc89c9886215bd3d Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 1 Aug 2025 15:35:24 -0400 Subject: [PATCH] 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 Reviewed-by: Jesse Natalie Reviewed-by: Karol Herbst Part-of: --- src/compiler/clc/nir_load_libclc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/compiler/clc/nir_load_libclc.c b/src/compiler/clc/nir_load_libclc.c index 28c9ca0783f..c4784350296 100644 --- a/src/compiler/clc/nir_load_libclc.c +++ b/src/compiler/clc/nir_load_libclc.c @@ -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. */