[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