[llvm-branch-commits] [libclc] libclc: Update ilogb implementation (PR #185877)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Mar 11 23:40:50 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/185877

>From 2ff44190498259bcaa024ac5c1e219d388e3fe08 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 11 Mar 2026 14:10:06 +0100
Subject: [PATCH] libclc: Update ilogb implementation

This was originally ported from rocm device libs in
d6d0454231ac489c50465d608ddf3f5d900e1535. Update for
more recent changes that were made there. This avoids
bithacking and improves value tracking. This also allows
using a common code path for all types.
---
 libclc/clc/lib/generic/math/clc_hypot.cl  |  2 +-
 libclc/clc/lib/generic/math/clc_ilogb.cl  | 14 +++--
 libclc/clc/lib/generic/math/clc_ilogb.inc | 76 +++--------------------
 3 files changed, 17 insertions(+), 75 deletions(-)

diff --git a/libclc/clc/lib/generic/math/clc_hypot.cl b/libclc/clc/lib/generic/math/clc_hypot.cl
index 7b5a5a7027da0..bac8339ee2822 100644
--- a/libclc/clc/lib/generic/math/clc_hypot.cl
+++ b/libclc/clc/lib/generic/math/clc_hypot.cl
@@ -11,7 +11,7 @@
 #include "clc/internal/clc.h"
 #include "clc/math/clc_fabs.h"
 #include "clc/math/clc_fmax.h"
-#include "clc/math/clc_frexp.h"
+#include "clc/math/clc_frexp_exp.h"
 #include "clc/math/clc_ldexp.h"
 #include "clc/math/clc_mad.h"
 #include "clc/math/clc_sqrt_fast.h"
diff --git a/libclc/clc/lib/generic/math/clc_ilogb.cl b/libclc/clc/lib/generic/math/clc_ilogb.cl
index 1ccc5754ca7f7..e96e547d2b6a1 100644
--- a/libclc/clc/lib/generic/math/clc_ilogb.cl
+++ b/libclc/clc/lib/generic/math/clc_ilogb.cl
@@ -6,11 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <clc/clc_convert.h>
-#include <clc/float/definitions.h>
-#include <clc/integer/clc_clz.h>
-#include <clc/internal/clc.h>
-#include <clc/math/math.h>
+#include "clc/clc_convert.h"
+#include "clc/float/definitions.h"
+#include "clc/integer/clc_clz.h"
+#include "clc/internal/clc.h"
+#include "clc/math/clc_frexp_exp.h"
+#include "clc/math/math.h"
+#include "clc/relational/clc_isinf.h"
+#include "clc/relational/clc_isnan.h"
+#include "clc/relational/clc_select.h"
 
 #define __CLC_BODY <clc_ilogb.inc>
 #include <clc/math/gentype.inc>
diff --git a/libclc/clc/lib/generic/math/clc_ilogb.inc b/libclc/clc/lib/generic/math/clc_ilogb.inc
index acbc70a9d1be2..4880af58a9794 100644
--- a/libclc/clc/lib/generic/math/clc_ilogb.inc
+++ b/libclc/clc/lib/generic/math/clc_ilogb.inc
@@ -6,76 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if __CLC_FPSIZE == 32
+_CLC_OVERLOAD _CLC_CONST _CLC_DEF __CLC_INTN __clc_ilogb(__CLC_GENTYPE x) {
+  __CLC_INTN r = __clc_frexp_exp(x) - 1;
 
-_CLC_OVERLOAD _CLC_DEF __CLC_INTN __clc_ilogb(__CLC_GENTYPE x) {
-  __CLC_UINTN ux = __CLC_AS_UINTN(x);
-  __CLC_UINTN ax = ux & EXSIGNBIT_SP32;
-  __CLC_INTN rs = (__CLC_INTN)LOG_MAGIC_NUM_SP32 -
-                  __CLC_AS_INTN(__clc_clz(ux & MANTBITS_SP32));
-  __CLC_INTN r = __CLC_AS_INTN(ax >> EXPSHIFTBITS_SP32) - EXPBIAS_SP32;
-  r = ax < 0x00800000U ? rs : r;
-  r = ax == 0 ? FP_ILOGB0 : r;
+  r = __clc_select(r, (__CLC_INTN)FP_ILOGBNAN,
+                   __CLC_CONVERT_UINTN(__clc_isnan(x)));
+  r = __clc_select(r, (__CLC_INTN)INT_MAX, __CLC_CONVERT_UINTN(__clc_isinf(x)));
+  r = __clc_select(r, (__CLC_INTN)FP_ILOGB0,
+                   __CLC_CONVERT_UINTN(x == __CLC_FP_LIT(0.0)));
 
-  // We could merge those 2 tests and have:
-  //
-  //    r = ax >= EXPBITS_SP32 ? 0x7fffffff : r
-  //
-  // since FP_ILOGBNAN is set to INT_MAX, but it's clearer this way and
-  // FP_ILOGBNAN can change without requiring changes to __clc_ilogb() code.
-  r = ax > EXPBITS_SP32 ? FP_ILOGBNAN : r;
-  r = ax == EXPBITS_SP32 ? 0x7fffffff : r;
   return r;
 }
-
-#endif
-
-#if __CLC_FPSIZE == 64
-
-_CLC_OVERLOAD _CLC_DEF __CLC_INTN __clc_ilogb(__CLC_GENTYPE x) {
-  __CLC_ULONGN ux = __CLC_AS_ULONGN(x);
-  __CLC_ULONGN ax = ux & ~SIGNBIT_DP64;
-  __CLC_INTN rs = (__CLC_INTN)LOG_MAGIC_NUM_DP64 -
-                  __CLC_CONVERT_INTN(__clc_clz(ax & MANTBITS_DP64));
-  __CLC_INTN r = __CLC_CONVERT_INTN(ax >> EXPSHIFTBITS_DP64) - EXPBIAS_DP64;
-  r = __CLC_CONVERT_INTN(ax < 0x0010000000000000UL) ? rs : r;
-  r = __CLC_CONVERT_INTN(ax == 0UL) ? (__CLC_INTN)FP_ILOGB0 : r;
-
-  // We could merge those 2 tests and have:
-  //
-  //    r = ax >= 0x7ff0000000000000UL ? 0x7fffffff : r
-  //
-  // since FP_ILOGBNAN is set to INT_MAX, but it's clearer this way and
-  // FP_ILOGBNAN can change without requiring changes to __clc_ilogb() code.
-  r = __CLC_CONVERT_INTN(ax > 0x7ff0000000000000UL) ? FP_ILOGBNAN : r;
-  r = __CLC_CONVERT_INTN(ax == 0x7ff0000000000000UL) ? 0x7fffffff : r;
-  return r;
-}
-
-#endif
-
-#if __CLC_FPSIZE == 16
-
-_CLC_OVERLOAD _CLC_DEF __CLC_INTN __clc_ilogb(__CLC_GENTYPE x) {
-  __CLC_USHORTN ux = __CLC_AS_USHORTN(x);
-  __CLC_USHORTN ax = ux & (__CLC_USHORTN)EXSIGNBIT_FP16;
-  __CLC_USHORTN mantx = ux & (__CLC_USHORTN)MANTBITS_FP16;
-  __CLC_INTN rs =
-      (__CLC_INTN)LOG_MAGIC_NUM_FP16 - __CLC_CONVERT_INTN(__clc_clz(mantx));
-  __CLC_INTN r =
-      __CLC_CONVERT_INTN(ax >> (__CLC_USHORTN)EXPSHIFTBITS_FP16) - EXPBIAS_FP16;
-  r = __CLC_CONVERT_INTN(ax < (__CLC_USHORTN)0x0400U) ? rs : r;
-  r = __CLC_CONVERT_INTN(ax == (__CLC_USHORTN)0) ? (__CLC_INTN)FP_ILOGB0 : r;
-
-  // We could merge those 2 tests and have:
-  //
-  //    r = ax >= EXPBITS_FP16 ? 0x7fffffff : r
-  //
-  // since FP_ILOGBNAN is set to INT_MAX, but it's clearer this way and
-  // FP_ILOGBNAN can change without requiring changes to __clc_ilogb() code.
-  r = __CLC_CONVERT_INTN(ax > (__CLC_USHORTN)EXPBITS_FP16) ? FP_ILOGBNAN : r;
-  r = __CLC_CONVERT_INTN(ax == (__CLC_USHORTN)EXPBITS_FP16) ? 0x7fffffff : r;
-  return r;
-}
-
-#endif



More information about the llvm-branch-commits mailing list