[libc-commits] [libc] [libc][math] Add cbrtbf16 math function (PR #180327)
via libc-commits
libc-commits at lists.llvm.org
Fri Feb 6 23:18:52 PST 2026
https://github.com/sohail103 updated https://github.com/llvm/llvm-project/pull/180327
>From af435ec1770a902207274e9f970cf0866cd1faa3 Mon Sep 17 00:00:00 2001
From: sohail103 <sohailraj.satapathy at gmail.com>
Date: Sat, 7 Feb 2026 12:19:14 +0530
Subject: [PATCH] [libc][math] Add cbrtbf16 math function
This patch adds an implementation of cbrtbf16 in libc, along with corresponding smoke and MPFR-based unit tests.
---
libc/config/baremetal/aarch64/entrypoints.txt | 1 +
libc/config/baremetal/arm/entrypoints.txt | 1 +
libc/config/baremetal/riscv/entrypoints.txt | 1 +
libc/config/darwin/aarch64/entrypoints.txt | 1 +
libc/config/darwin/x86_64/entrypoints.txt | 1 +
libc/config/gpu/amdgpu/entrypoints.txt | 1 +
libc/config/gpu/nvptx/entrypoints.txt | 1 +
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/arm/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/config/windows/entrypoints.txt | 1 +
libc/docs/headers/math/index.rst | 2 +-
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/cbrtbf16.h | 22 ++++++
libc/src/math/generic/CMakeLists.txt | 14 ++++
libc/src/math/generic/cbrtbf16.cpp | 21 ++++++
libc/test/src/math/CMakeLists.txt | 12 +++
libc/test/src/math/cbrtbf16_test.cpp | 35 +++++++++
libc/test/src/math/smoke/CMakeLists.txt | 11 +++
libc/test/src/math/smoke/cbrtbf16_test.cpp | 75 +++++++++++++++++++
21 files changed, 204 insertions(+), 1 deletion(-)
create mode 100644 libc/src/math/cbrtbf16.h
create mode 100644 libc/src/math/generic/cbrtbf16.cpp
create mode 100644 libc/test/src/math/cbrtbf16_test.cpp
create mode 100644 libc/test/src/math/smoke/cbrtbf16_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 742d96761c415..c725a3b45d50f 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -350,6 +350,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 95cb0dea8e49e..ea214276f1b0b 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -353,6 +353,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 3fc71280f5163..5a2525a9d7ad1 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -351,6 +351,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 3909417f9730d..1749fbcaaeec0 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -166,6 +166,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index e899bf97ea3f6..27e50b9e96e96 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -277,6 +277,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
libc.src.math.llrintbf16
libc.src.math.llroundbf16
libc.src.math.log_bf16
+ libc.src.math.cbrtbf16
libc.src.math.logbbf16
libc.src.math.lrintbf16
libc.src.math.lroundbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 0dda7d5c683ec..4db38718f59d8 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -297,6 +297,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 6070fb5b17b3c..9574496a19c60 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -297,6 +297,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 970c825bbfc96..01e8c261214b7 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -436,6 +436,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index f04ac40145d3a..63ed280a6f1b4 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -263,6 +263,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atanhf
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 7baf4de9d8a5b..6a172c9338b92 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -440,6 +440,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9399b284fa2da..8fe21e372e6cd 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -482,6 +482,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.canonicalizel
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.ceil
libc.src.math.ceilf
libc.src.math.ceill
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 3a76595b258e2..8c135447ca3b6 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -143,6 +143,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.atanhf
libc.src.math.cbrt
libc.src.math.cbrtf
+ libc.src.math.cbrtbf16
libc.src.math.copysign
libc.src.math.copysignf
libc.src.math.copysignl
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 51bb17ff8dab6..cc32e1931a301 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -281,7 +281,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| atanpi | | | | |check| | | | 7.12.4.10 | F.10.1.10 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| cbrt | |check| | |check| | | | | | 7.12.7.1 | F.10.4.1 |
+| cbrt | |check| | |check| | | | | |check| | 7.12.7.1 | F.10.4.1 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
| compoundn | | | | | | | 7.12.7.2 | F.10.4.2 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index e37e22fdb58e6..035fe1048fca3 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -91,6 +91,7 @@ add_math_entrypoint_object(iscanonicalbf16)
add_math_entrypoint_object(cbrt)
add_math_entrypoint_object(cbrtf)
+add_math_entrypoint_object(cbrtbf16)
add_math_entrypoint_object(ceil)
add_math_entrypoint_object(ceilf)
diff --git a/libc/src/math/cbrtbf16.h b/libc/src/math/cbrtbf16.h
new file mode 100644
index 0000000000000..e327b58eb447c
--- /dev/null
+++ b/libc/src/math/cbrtbf16.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for cbrtbf16 ----------------------*- 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_CBRTBF16_H
+#define LLVM_LIBC_SRC_MATH_CBRTBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 cbrtbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_CBRTBF16_H
+
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index be3f724e10a8b..0d54c891417b1 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -5155,6 +5155,20 @@ add_entrypoint_object(
libc.src.__support.math.cbrt
)
+add_entrypoint_object (
+ cbrtbf16
+ SRCS
+ cbrtbf16.cpp
+ HDRS
+ ../cbrtbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.math.generic.cbrt
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
add_entrypoint_object(
dmull
SRCS
diff --git a/libc/src/math/generic/cbrtbf16.cpp b/libc/src/math/generic/cbrtbf16.cpp
new file mode 100644
index 0000000000000..131899acae928
--- /dev/null
+++ b/libc/src/math/generic/cbrtbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of cbrtbf16 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/cbrtbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/math/cbrtf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, cbrtbf16, (bfloat16 x)) {
+ return static_cast<bfloat16>(math::cbrtf(static_cast<float>(x)));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index ff5c511922171..234001de14be6 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2974,6 +2974,18 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ cbrtbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ cbrtbf16_test.cpp
+ DEPENDS
+ libc.src.math.cbrtbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
dmull_test
NEED_MPFR
diff --git a/libc/test/src/math/cbrtbf16_test.cpp b/libc/test/src/math/cbrtbf16_test.cpp
new file mode 100644
index 0000000000000..da75dd30fa7f2
--- /dev/null
+++ b/libc/test/src/math/cbrtbf16_test.cpp
@@ -0,0 +1,35 @@
+//===-- Exhaustive test for cbrtbf16 --------------------------------------===//
+//
+// 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/__support/FPUtil/bfloat16.h"
+#include "src/math/cbrtbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcCbrtbf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// for the exhaustive test, we test with every 16-bit combination
+// and skip NaN cases. v is uint32_t to prevent integer overflow and
+// wraparound to 0.
+TEST_F(LlvmLibcCbrtbf16Test, Exhaustive) {
+ for (uint32_t v = 0x00000; v < 0x10000; ++v) {
+ bfloat16 x =
+ LIBC_NAMESPACE::fputil::FPBits<bfloat16>(static_cast<uint16_t>(v))
+ .get_val();
+
+ LIBC_NAMESPACE::fputil::FPBits<bfloat16> bits(x); // NaN checking
+ if (bits.is_nan())
+ continue;
+
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cbrt, x,
+ LIBC_NAMESPACE::cbrtbf16(x), 0.5);
+ }
+}
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 5afd3a9f22967..eaece7c23c3dc 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -5984,6 +5984,17 @@ add_fp_unittest(
libc.src.math.cbrt
)
+add_fp_unittest(
+ cbrtbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ cbrtbf16_test.cpp
+ DEPENDS
+ libc.src.math.cbrtbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_fp_unittest(
dmull_test
SUITE
diff --git a/libc/test/src/math/smoke/cbrtbf16_test.cpp b/libc/test/src/math/smoke/cbrtbf16_test.cpp
new file mode 100644
index 0000000000000..ab38e5cc5d8d3
--- /dev/null
+++ b/libc/test/src/math/smoke/cbrtbf16_test.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// Unittests for cbrtbf16
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/cbrtbf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcCbrtbf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
+
+using LIBC_NAMESPACE::testing::tlog;
+
+TEST_F(LlvmLibcCbrtbf16Test, SpecialNumbers) {
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cbrtbf16(sNaN), FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cbrtbf16(aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::cbrtbf16(inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::cbrtbf16(neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::cbrtbf16(zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::cbrtbf16(neg_zero));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(1.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-1.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(-1.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(2.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(8.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-2.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(-8.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(3.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(27.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-3.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(-27.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(5.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(125.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-5.0f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(-125.0f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.0p42f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(0x1.0p126f)));
+ EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.0p42f),
+ LIBC_NAMESPACE::cbrtbf16(bfloat16(-0x1.0p126f)));
+}
+
+#ifdef LIBC_TEST_FTZ_DAZ
+
+using namespace LIBC_NAMESPACE::testing;
+
+// the float version includes explicit FTZ-mode checks for subnormal
+// outputs using hex expectations. for bfloat16, this is unnecessary.
+// if x=2^e then cbrt(x)=2^(e/3). to produce a subnormal result, we would
+// need e/3 < -126, i.e e<-378. Since the smallest representable exponent
+// in bfloat16 is -133, no finite bfloat16 input can produce a subnormal
+// cube root. therefore, explicit subnormal output checks are omitted here.
+
+TEST_F(LlvmLibcCbrtbf16Test, DAZMode) {
+ ModifyMXCSR mxcsr(DAZ);
+
+ EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(min_denormal));
+ EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(max_denormal));
+}
+
+TEST_F(LlvmLibcCbrtbf16Test, FTZDAZMode) {
+ ModifyMXCSR mxcsr(FTZ | DAZ);
+
+ EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(min_denormal));
+ EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(max_denormal));
+}
+
+#endif
More information about the libc-commits
mailing list