[libc-commits] [libc] cd7e200 - [libc][math] Add cbrtbf16 math function (#180327)
via libc-commits
libc-commits at lists.llvm.org
Tue Mar 10 09:59:32 PDT 2026
Author: sohail
Date: 2026-03-10T12:59:26-04:00
New Revision: cd7e200e426ee7418045d357e413f6de137eeb4a
URL: https://github.com/llvm/llvm-project/commit/cd7e200e426ee7418045d357e413f6de137eeb4a
DIFF: https://github.com/llvm/llvm-project/commit/cd7e200e426ee7418045d357e413f6de137eeb4a.diff
LOG: [libc][math] Add cbrtbf16 math function (#180327)
Add a bfloat16 implementation of cbrt along with corresponding smoke
tests and an MPFR-based exhaustive unit test.
Fixes #179729
Added:
libc/src/math/cbrtbf16.h
libc/src/math/generic/cbrtbf16.cpp
libc/test/src/math/cbrtbf16_test.cpp
libc/test/src/math/smoke/cbrtbf16_test.cpp
Modified:
libc/config/baremetal/aarch64/entrypoints.txt
libc/config/baremetal/arm/entrypoints.txt
libc/config/baremetal/riscv/entrypoints.txt
libc/config/darwin/aarch64/entrypoints.txt
libc/config/darwin/x86_64/entrypoints.txt
libc/config/gpu/amdgpu/entrypoints.txt
libc/config/gpu/nvptx/entrypoints.txt
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/arm/entrypoints.txt
libc/config/linux/riscv/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/config/windows/entrypoints.txt
libc/docs/headers/math/index.rst
libc/src/math/CMakeLists.txt
libc/src/math/generic/CMakeLists.txt
libc/test/src/math/CMakeLists.txt
libc/test/src/math/smoke/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 278e1f5afde70..4e720a234d471 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -355,6 +355,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 9a6b9cbf3daef..c61afd0fdcc62 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -361,6 +361,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 1e297d14cae20..24e9cc502b731 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -356,6 +356,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 ced8d1fef0109..5085e95a643ec 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -171,6 +171,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 a65b6f0274fd8..0441207ace96b 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -299,6 +299,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 fee0038c88cc0..f127ba6358b43 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -299,6 +299,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 92210a72ee754..7957847200960 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -441,6 +441,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 6ee0ebf2b412d..48d5972f71ce0 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -268,6 +268,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 878f8d42d6d7c..7ebaa4f165c0d 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -445,6 +445,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 f26b818466240..4cec9708b0403 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -490,6 +490,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 fc2f3dbe7765f..18910b5f98459 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -147,6 +147,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 e8b3fe63b2a6c..ee2b6d9b7bd16 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 e617950368994..766feb0606c64 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -93,6 +93,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..beef9278cbe1a
--- /dev/null
+++ b/libc/src/math/cbrtbf16.h
@@ -0,0 +1,21 @@
+//===-- 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 d067efdae5e89..b9de548c8bedb 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4937,6 +4937,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..742cee8ae1429
--- /dev/null
+++ b/libc/src/math/generic/cbrtbf16.cpp
@@ -0,0 +1,18 @@
+//===-- 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 73b5ebf5a856e..90afe842e9dec 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -3011,6 +3011,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..cf5154e8cb6ea
--- /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);
+ }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 3d52873c40bb8..185f646e3aa9c 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -6018,6 +6018,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