[libc-commits] [libc] [libc][math] Add isnanbf16 function (PR #199556)

via libc-commits libc-commits at lists.llvm.org
Mon May 25 10:22:56 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Tarun Akash Kombol Baha (TarunAkash)

<details>
<summary>Changes</summary>

Adds the bfloat16 variant of `isnan`, addressing one of the three missing
variants requested in issue #<!-- -->195400.

### Implementation
- Algorithm lives in `libc/src/__support/math/isnanbf16.h`, mirroring the
  pattern used by `issignalingbf16`.
- The check is `fputil::FPBits<bfloat16>(x).is_nan()`, consistent with the
  refactor direction noted on the issue thread.
- No `LIBC_TYPES_HAS_*` guard is needed because `bfloat16` is libc's own
  software-defined struct, always available.

### Testing
Added a new shared `IsNanTest.h` helper (mirrors `IsSignalingTest.h`) and a
two-line `isnanbf16_test.cpp` that instantiates it for `bfloat16`. Verified
the smoke test passes locally:

[ RUN      ] LlvmLibcIsNanTest.SpecialNumbers
[       OK ] LlvmLibcIsNanTest.SpecialNumbers
[ RUN      ] LlvmLibcIsNanTest.RoundedNumbers
[       OK ] LlvmLibcIsNanTest.RoundedNumbers
Ran 2 tests.  PASS: 2  FAIL: 0



Closes #<!-- -->195400.

---
Full diff: https://github.com/llvm/llvm-project/pull/199556.diff


22 Files Affected:

- (modified) libc/config/baremetal/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/baremetal/arm/entrypoints.txt (+1) 
- (modified) libc/config/baremetal/riscv/entrypoints.txt (+1) 
- (modified) libc/config/darwin/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/darwin/x86_64/entrypoints.txt (+1) 
- (modified) libc/config/freebsd/x86_64/entrypoints.txt (+1) 
- (modified) libc/config/gpu/amdgpu/entrypoints.txt (+1) 
- (modified) libc/config/gpu/nvptx/entrypoints.txt (+1) 
- (modified) libc/config/linux/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/linux/arm/entrypoints.txt (+1) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+1) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1) 
- (modified) libc/config/windows/entrypoints.txt (+1) 
- (modified) libc/src/__support/math/CMakeLists.txt (+10) 
- (added) libc/src/__support/math/isnanbf16.h (+26) 
- (modified) libc/src/math/CMakeLists.txt (+1) 
- (modified) libc/src/math/generic/CMakeLists.txt (+10) 
- (added) libc/src/math/generic/isnanbf16.cpp (+18) 
- (added) libc/src/math/isnanbf16.h (+21) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+13) 
- (added) libc/test/src/math/smoke/IsNanTest.h (+60) 
- (added) libc/test/src/math/smoke/isnanbf16_test.cpp (+14) 


``````````diff
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index dcb50135232e2..1627e8a5290e5 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -833,6 +833,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index fac62bac939cc..eb6e5fe63dbcf 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -844,6 +844,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index a3b96225ff09d..8c53e354929a4 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -841,6 +841,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 914d2b7918da1..e418ab0134ba2 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -654,6 +654,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index b941c968255e8..92985417e4cd4 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -276,6 +276,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 31d421555624d..681a29b923a6f 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -598,6 +598,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index c76900a8371f7..c32d31e6f38b9 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -682,6 +682,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 6538732f785f5..5fee1f890d74a 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -684,6 +684,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a50923fddec54..5231bd5a115e3 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -946,6 +946,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 49b30ef1830f3..d15cd3e461efe 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -524,6 +524,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 51c769d853a52..9cf0352e142b9 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -967,6 +967,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5545790fecd85..15697f0a3d560 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1032,6 +1032,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 94d1d00e676d9..414e89929bede 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -366,6 +366,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.hypotbf16
   libc.src.math.ilogbbf16
   libc.src.math.iscanonicalbf16
+  libc.src.math.isnanbf16
   libc.src.math.issignalingbf16
   libc.src.math.ldexpbf16
   libc.src.math.llogbbf16
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 9e3ec26cdc881..1f0d7663cfd43 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1686,6 +1686,16 @@ add_header_library(
     libc.src.__support.macros.config
 )
 
+add_header_library(
+  isnanbf16
+  HDRS
+    isnanbf16.h
+  DEPENDS
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.macros.config
+)
+
 add_header_library(
   isnanf
   HDRS
diff --git a/libc/src/__support/math/isnanbf16.h b/libc/src/__support/math/isnanbf16.h
new file mode 100644
index 0000000000000..09b43a2edc0ae
--- /dev/null
+++ b/libc/src/__support/math/isnanbf16.h
@@ -0,0 +1,26 @@
+//===-- Implementation header for isnanbf16 ---------------------*- C++ -*-===//
+//
+// 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 LLVM_LIBC_SRC___SUPPORT_MATH_ISNANBF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ISNANBF16_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+LIBC_INLINE constexpr int isnanbf16(bfloat16 x) {
+  return fputil::FPBits<bfloat16>(x).is_nan();
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ISNANBF16_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index b53817e2a1729..4c3086d7180ae 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -368,6 +368,7 @@ add_math_entrypoint_object(ilogbbf16)
 add_math_entrypoint_object(isnan)
 add_math_entrypoint_object(isnanf)
 add_math_entrypoint_object(isnanl)
+add_math_entrypoint_object(isnanbf16)
 
 add_math_entrypoint_object(issignaling)
 add_math_entrypoint_object(issignalingf)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 7ccbddba07b8d..2562b3fcb2af8 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3021,6 +3021,16 @@ add_entrypoint_object(
     libc.src.__support.math.isnan
 )
 
+add_entrypoint_object(
+  isnanbf16
+  SRCS
+    isnanbf16.cpp
+  HDRS
+    ../isnanbf16.h
+  DEPENDS
+    libc.src.__support.math.isnanbf16
+)
+
 add_entrypoint_object(
   isnanf
   SRCS
diff --git a/libc/src/math/generic/isnanbf16.cpp b/libc/src/math/generic/isnanbf16.cpp
new file mode 100644
index 0000000000000..df7cee182a34e
--- /dev/null
+++ b/libc/src/math/generic/isnanbf16.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of isnanbf16 function ------------------------------===//
+//
+// 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 "src/math/isnanbf16.h"
+#include "src/__support/math/isnanbf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, isnanbf16, (bfloat16 x)) {
+  return math::isnanbf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/isnanbf16.h b/libc/src/math/isnanbf16.h
new file mode 100644
index 0000000000000..a5ba6f09e3001
--- /dev/null
+++ b/libc/src/math/isnanbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for isnanbf16 ---------------------*- C++ -*-===//
+//
+// 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 LLVM_LIBC_SRC_MATH_ISNANBF16_H
+#define LLVM_LIBC_SRC_MATH_ISNANBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int isnanbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISNANBF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 28b85b1a25bbd..ac5033875accb 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -2119,6 +2119,19 @@ add_fp_unittest(
     libc.src.math.issignalingf128
 )
 
+add_fp_unittest(
+  isnanbf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    isnanbf16_test.cpp
+  HDRS
+    IsNanTest.h
+  DEPENDS
+    libc.src.math.isnanbf16
+    libc.src.__support.FPUtil.bfloat16
+)
+
 add_fp_unittest(
   issignalingbf16_test
   SUITE
diff --git a/libc/test/src/math/smoke/IsNanTest.h b/libc/test/src/math/smoke/IsNanTest.h
new file mode 100644
index 0000000000000..f83e6cf1051fe
--- /dev/null
+++ b/libc/test/src/math/smoke/IsNanTest.h
@@ -0,0 +1,60 @@
+//===-- Utility class to test different flavors of isnan --------*- C++ -*-===//
+//
+// 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 LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISNANTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISNANTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "hdr/math_macros.h"
+
+template <typename T>
+class IsNanTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef int (*IsNanFunc)(T);
+
+  void testSpecialNumbers(IsNanFunc func) {
+    EXPECT_EQ(func(aNaN), 1);
+    EXPECT_EQ(func(neg_aNaN), 1);
+    EXPECT_EQ(func(sNaN), 1);
+    EXPECT_EQ(func(neg_sNaN), 1);
+    EXPECT_EQ(func(inf), 0);
+    EXPECT_EQ(func(neg_inf), 0);
+    EXPECT_EQ(func(min_normal), 0);
+    EXPECT_EQ(func(max_normal), 0);
+    EXPECT_EQ(func(neg_max_normal), 0);
+    EXPECT_EQ(func(min_denormal), 0);
+    EXPECT_EQ(func(neg_min_denormal), 0);
+    EXPECT_EQ(func(max_denormal), 0);
+    EXPECT_EQ(func(zero), 0);
+    EXPECT_EQ(func(neg_zero), 0);
+  }
+
+  void testRoundedNumbers(IsNanFunc func) {
+    EXPECT_EQ(func(T(1.0)), 0);
+    EXPECT_EQ(func(T(-1.0)), 0);
+    EXPECT_EQ(func(T(10.0)), 0);
+    EXPECT_EQ(func(T(-10.0)), 0);
+    EXPECT_EQ(func(T(1234.0)), 0);
+    EXPECT_EQ(func(T(-1234.0)), 0);
+  }
+};
+
+#define LIST_ISNAN_TESTS(T, func)                                        \
+  using LlvmLibcIsNanTest = IsNanTest<T>;                          \
+  TEST_F(LlvmLibcIsNanTest, SpecialNumbers) {                            \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  TEST_F(LlvmLibcIsNanTest, RoundedNumbers) { testRoundedNumbers(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISNANTEST_H
diff --git a/libc/test/src/math/smoke/isnanbf16_test.cpp b/libc/test/src/math/smoke/isnanbf16_test.cpp
new file mode 100644
index 0000000000000..fcac34dfffdb6
--- /dev/null
+++ b/libc/test/src/math/smoke/isnanbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for isnanbf16 -------------------------------------------===//
+//
+// 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 "IsNanTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/isnanbf16.h"
+
+LIST_ISNAN_TESTS(bfloat16, LIBC_NAMESPACE::isnanbf16)

``````````

</details>


https://github.com/llvm/llvm-project/pull/199556


More information about the libc-commits mailing list