[llvm-branch-commits] [libclc] libclc: Add canonicalize utility functions (PR #187357)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 19 01:02:35 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/187357
>From 3665db80697a24bdc825631fd7b34f0410e01354 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 18 Mar 2026 18:47:02 +0100
Subject: [PATCH] libclc: Add canonicalize utility functions
This is mostly to work around spirv's canonicalize still
being broken.
---
.../clc/include/clc/math/clc_canonicalize.h | 21 +++++++++
.../clc/include/clc/math/clc_flush_if_daz.h | 21 +++++++++
libclc/clc/include/clc/math/math.h | 10 -----
libclc/clc/lib/clspv/math/clc_sw_fma.cl | 7 +--
libclc/clc/lib/generic/CMakeLists.txt | 2 +
.../clc/lib/generic/math/clc_canonicalize.cl | 15 +++++++
.../clc/lib/generic/math/clc_flush_if_daz.cl | 15 +++++++
.../clc/lib/generic/math/clc_flush_if_daz.inc | 43 +++++++++++++++++++
libclc/clc/lib/generic/math/clc_remquo.cl | 1 +
libclc/clc/lib/generic/math/clc_remquo.inc | 4 +-
10 files changed, 124 insertions(+), 15 deletions(-)
create mode 100644 libclc/clc/include/clc/math/clc_canonicalize.h
create mode 100644 libclc/clc/include/clc/math/clc_flush_if_daz.h
create mode 100644 libclc/clc/lib/generic/math/clc_canonicalize.cl
create mode 100644 libclc/clc/lib/generic/math/clc_flush_if_daz.cl
create mode 100644 libclc/clc/lib/generic/math/clc_flush_if_daz.inc
diff --git a/libclc/clc/include/clc/math/clc_canonicalize.h b/libclc/clc/include/clc/math/clc_canonicalize.h
new file mode 100644
index 0000000000000..527463e5281b1
--- /dev/null
+++ b/libclc/clc/include/clc/math/clc_canonicalize.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLC_MATH_CLC_CANONICALIZE_H__
+#define __CLC_MATH_CLC_CANONICALIZE_H__
+
+#include "clc/internal/clc.h"
+
+#define __CLC_BODY "clc/math/unary_decl.inc"
+#define __CLC_FUNCTION __clc_canonicalize
+
+#include "clc/math/gentype.inc"
+
+#undef __CLC_FUNCTION
+
+#endif // __CLC_MATH_CLC_CANONICALIZE_H__
diff --git a/libclc/clc/include/clc/math/clc_flush_if_daz.h b/libclc/clc/include/clc/math/clc_flush_if_daz.h
new file mode 100644
index 0000000000000..9e9bf99d9e4bc
--- /dev/null
+++ b/libclc/clc/include/clc/math/clc_flush_if_daz.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CLC_MATH_CLC_FLUSH_IF_DAZ_H__
+#define __CLC_MATH_CLC_FLUSH_IF_DAZ_H__
+
+#include "clc/internal/clc.h"
+
+#define __CLC_BODY "clc/math/unary_decl.inc"
+#define __CLC_FUNCTION __clc_flush_if_daz
+
+#include "clc/math/gentype.inc"
+
+#undef __CLC_FUNCTION
+
+#endif // __CLC_MATH_CLC_FLUSH_IF_DAZ_H__
diff --git a/libclc/clc/include/clc/math/math.h b/libclc/clc/include/clc/math/math.h
index 15b1272b37466..a676c357f4633 100644
--- a/libclc/clc/include/clc/math/math.h
+++ b/libclc/clc/include/clc/math/math.h
@@ -58,16 +58,6 @@
#define LOG_MAGIC_NUM_SP32 (1 + NUMEXPBITS_SP32 - EXPBIAS_SP32)
-_CLC_OVERLOAD _CLC_INLINE float __clc_flush_denormal_if_not_supported(float x) {
- int ix = __clc_as_int(x);
- if (__clc_denormals_are_zero_fp32() && ((ix & EXPBITS_SP32) == 0) &&
- ((ix & MANTBITS_SP32) != 0)) {
- ix &= SIGNBIT_SP32;
- x = __clc_as_float(ix);
- }
- return x;
-}
-
#ifdef cl_khr_fp64
#define SIGNBIT_DP64 0x8000000000000000L
diff --git a/libclc/clc/lib/clspv/math/clc_sw_fma.cl b/libclc/clc/lib/clspv/math/clc_sw_fma.cl
index 306aad5142120..e73f53e6bcd76 100644
--- a/libclc/clc/lib/clspv/math/clc_sw_fma.cl
+++ b/libclc/clc/lib/clspv/math/clc_sw_fma.cl
@@ -17,6 +17,7 @@
#include "clc/integer/clc_hadd.h"
#include "clc/integer/clc_mul_hi.h"
#include "clc/integer/definitions.h"
+#include "clc/math/clc_flush_if_daz.h"
#include "clc/math/clc_mad.h"
#include "clc/math/math.h"
#include "clc/relational/clc_isinf.h"
@@ -127,9 +128,9 @@ _CLC_DEF _CLC_OVERLOAD float __clc_sw_fma(float a, float b, float c) {
return c;
}
- a = __clc_flush_denormal_if_not_supported(a);
- b = __clc_flush_denormal_if_not_supported(b);
- c = __clc_flush_denormal_if_not_supported(c);
+ a = __clc_flush_if_daz(a);
+ b = __clc_flush_if_daz(b);
+ c = __clc_flush_if_daz(c);
if (a == 0.0f || b == 0.0f) {
return c;
diff --git a/libclc/clc/lib/generic/CMakeLists.txt b/libclc/clc/lib/generic/CMakeLists.txt
index f9eb15a0aafda..130f396b53bfd 100644
--- a/libclc/clc/lib/generic/CMakeLists.txt
+++ b/libclc/clc/lib/generic/CMakeLists.txt
@@ -66,6 +66,7 @@ libclc_configure_source_list(CLC_GENERIC_SOURCES
math/clc_atan2pi.cl
math/clc_atanh.cl
math/clc_atanpi.cl
+ math/clc_canonicalize.cl
math/clc_cbrt.cl
math/clc_ceil.cl
math/clc_copysign.cl
@@ -87,6 +88,7 @@ libclc_configure_source_list(CLC_GENERIC_SOURCES
math/clc_fabs.cl
math/clc_fdim.cl
math/clc_floor.cl
+ math/clc_flush_if_daz.cl
math/clc_fma.cl
math/clc_fmax.cl
math/clc_fmin.cl
diff --git a/libclc/clc/lib/generic/math/clc_canonicalize.cl b/libclc/clc/lib/generic/math/clc_canonicalize.cl
new file mode 100644
index 0000000000000..5b0ae52a14505
--- /dev/null
+++ b/libclc/clc/lib/generic/math/clc_canonicalize.cl
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clc/math/clc_canonicalize.h"
+
+#define __CLC_FUNCTION __clc_canonicalize
+#define __CLC_IMPL_FUNCTION(x) __builtin_elementwise_canonicalize
+#define __CLC_BODY "clc/shared/unary_def.inc"
+
+#include "clc/math/gentype.inc"
diff --git a/libclc/clc/lib/generic/math/clc_flush_if_daz.cl b/libclc/clc/lib/generic/math/clc_flush_if_daz.cl
new file mode 100644
index 0000000000000..1abb18336eaa6
--- /dev/null
+++ b/libclc/clc/lib/generic/math/clc_flush_if_daz.cl
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "clc/clc_convert.h"
+#include "clc/math/clc_canonicalize.h"
+#include "clc/math/clc_flush_if_daz.h"
+#include "clc/math/clc_subnormal_config.h"
+#include "clc/math/math.h"
+
+#define __CLC_BODY "clc_flush_if_daz.inc"
+#include "clc/math/gentype.inc"
diff --git a/libclc/clc/lib/generic/math/clc_flush_if_daz.inc b/libclc/clc/lib/generic/math/clc_flush_if_daz.inc
new file mode 100644
index 0000000000000..5ae1b39d6121f
--- /dev/null
+++ b/libclc/clc/lib/generic/math/clc_flush_if_daz.inc
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if __CLC_FPSIZE == 16
+#define __CLC_GENTYPE_EXPBITS (__CLC_S_GENTYPE) EXPBITS_FP16
+#define __CLC_GENTYPE_MANTBITS (__CLC_S_GENTYPE) MANTBITS_FP16
+#define __CLC_GENTYPE_SIGNBIT (__CLC_S_GENTYPE) SIGNBIT_FP16
+#elif __CLC_FPSIZE == 32
+#define __CLC_GENTYPE_EXPBITS (__CLC_S_GENTYPE) EXPBITS_SP32
+#define __CLC_GENTYPE_MANTBITS (__CLC_S_GENTYPE) MANTBITS_SP32
+#define __CLC_GENTYPE_SIGNBIT (__CLC_S_GENTYPE) SIGNBIT_SP32
+#elif __CLC_FPSIZE == 64
+#define __CLC_GENTYPE_EXPBITS (__CLC_S_GENTYPE) EXPBITS_DP64
+#define __CLC_GENTYPE_MANTBITS (__CLC_S_GENTYPE) MANTBITS_DP64
+#define __CLC_GENTYPE_SIGNBIT (__CLC_S_GENTYPE) SIGNBIT_DP64
+#endif
+
+_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_flush_if_daz(__CLC_GENTYPE x) {
+ if (!__CLC_GENTYPE_DENORMS_ARE_ZERO)
+ return x;
+
+ // Hack around canonicalize not working on spirv.
+#if defined(CLC_SPIRV) || defined(CLC_CLSPV)
+ __CLC_S_GENTYPE ix = __CLC_AS_S_GENTYPE(x);
+ __CLC_S_GENTYPE should_flush =
+ ((ix & __CLC_GENTYPE_EXPBITS) == (__CLC_S_GENTYPE)0) &&
+ ((ix & __CLC_GENTYPE_MANTBITS) != (__CLC_S_GENTYPE)0);
+ __CLC_S_GENTYPE signbit = ix &= __CLC_GENTYPE_SIGNBIT;
+ __CLC_S_GENTYPE result = should_flush ? signbit : ix;
+ return __CLC_AS_GENTYPE(result);
+#else
+ return __clc_canonicalize(x);
+#endif
+}
+
+#undef __CLC_GENTYPE_EXPBITS
+#undef __CLC_GENTYPE_MANTBITS
+#undef __CLC_GENTYPE_SIGNBIT
diff --git a/libclc/clc/lib/generic/math/clc_remquo.cl b/libclc/clc/lib/generic/math/clc_remquo.cl
index 6f6a7fc6bdcfa..e254093d591d4 100644
--- a/libclc/clc/lib/generic/math/clc_remquo.cl
+++ b/libclc/clc/lib/generic/math/clc_remquo.cl
@@ -10,6 +10,7 @@
#include "clc/integer/clc_clz.h"
#include "clc/internal/clc.h"
#include "clc/math/clc_floor.h"
+#include "clc/math/clc_flush_if_daz.h"
#include "clc/math/clc_fma.h"
#include "clc/math/clc_ldexp.h"
#include "clc/math/clc_subnormal_config.h"
diff --git a/libclc/clc/lib/generic/math/clc_remquo.inc b/libclc/clc/lib/generic/math/clc_remquo.inc
index 3a76ffed7f039..cf8a5ebcea20c 100644
--- a/libclc/clc/lib/generic/math/clc_remquo.inc
+++ b/libclc/clc/lib/generic/math/clc_remquo.inc
@@ -8,8 +8,8 @@
_CLC_DEF _CLC_OVERLOAD float __clc_remquo(float x, float y,
__CLC_ADDRESS_SPACE int *quo) {
- x = __clc_flush_denormal_if_not_supported(x);
- y = __clc_flush_denormal_if_not_supported(y);
+ x = __clc_flush_if_daz(x);
+ y = __clc_flush_if_daz(y);
int ux = __clc_as_int(x);
int ax = ux & EXSIGNBIT_SP32;
float xa = __clc_as_float(ax);
More information about the llvm-branch-commits
mailing list