Skip to content

Conversation

krishna2803
Copy link
Contributor

This PR adds fmodbf16 basic math function for BFloat16 type along with the tests.

Signed-off-by: Krishna Pandey <[email protected]>
…signaling}bf16 math functions

Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Krishna Pandey (krishna2803)

Changes

This PR adds fmodbf16 basic math function for BFloat16 type along with the tests.


Full diff: https://github.com/llvm/llvm-project/pull/155575.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/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/docs/headers/math/index.rst (+1-1)
  • (modified) libc/src/math/CMakeLists.txt (+1)
  • (added) libc/src/math/fmodbf16.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+14)
  • (added) libc/src/math/generic/fmodbf16.cpp (+21)
  • (modified) libc/test/src/math/exhaustive/CMakeLists.txt (+16)
  • (added) libc/test/src/math/exhaustive/fmodbf16_test.cpp (+42)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+17)
  • (modified) libc/test/src/math/smoke/FModTest.h (+13-12)
  • (added) libc/test/src/math/smoke/fmodbf16_test.cpp (+14)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 637be4f19d5b7..782769e2c0ef9 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -788,6 +788,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 19aedb0a8677d..f112c2b36fdf3 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index cfbb598cbe4bf..53e5914b9ec32 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 26e97d8993039..b4e210ad3ae0b 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -621,6 +621,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 0556a6f7a4715..95392f7718849 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -264,6 +264,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 8817972480aac..737d1bb3ac61c 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -647,6 +647,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index db762ed5c74d6..c06d63576bbd3 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -649,6 +649,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 0a2ebfa3f8720..9aeb6a7361cd5 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -876,6 +876,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index ea1c5c0558272..591c57d479dc2 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -491,6 +491,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index d5180b77c3af0..b2cd511506607 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -894,6 +894,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c64db2cc3548f..d5db2606a9887 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -927,6 +927,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 9f825bdf657e9..2da48c32d0af3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -337,6 +337,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index a707b37894afc..4520f56137bd7 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -175,7 +175,7 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fminimum_num     | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.12.9              | F.10.9.5                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                |                        | 7.12.10.1              | F.10.7.1                   |
+| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.10.1              | F.10.7.1                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fmul             | N/A              | |check|         | |check|                | N/A                  | |check|\*              | N/A                    | 7.12.14.3              | F.10.11                    |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 4b325f773b35f..d2fba849f7e27 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -306,6 +306,7 @@ add_math_entrypoint_object(fmodf)
 add_math_entrypoint_object(fmodl)
 add_math_entrypoint_object(fmodf16)
 add_math_entrypoint_object(fmodf128)
+add_math_entrypoint_object(fmodbf16)
 
 add_math_entrypoint_object(frexp)
 add_math_entrypoint_object(frexpf)
diff --git a/libc/src/math/fmodbf16.h b/libc/src/math/fmodbf16.h
new file mode 100644
index 0000000000000..176dbcc83eda0
--- /dev/null
+++ b/libc/src/math/fmodbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmodbf16 ----------------------*- 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_FMODBF16_H
+#define LLVM_LIBC_SRC_MATH_FMODBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmodbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMODBF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b1fcbf356777a..b9ef116e3dbb9 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4015,6 +4015,20 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.generic.fmod
 )
 
+add_entrypoint_object(
+  fmodbf16
+  SRCS
+    fmodbf16.cpp
+  HDRS
+    ../fmodbf16.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.generic.fmod
+)
+
 add_entrypoint_object(
   fromfp
   SRCS
diff --git a/libc/src/math/generic/fmodbf16.cpp b/libc/src/math/generic/fmodbf16.cpp
new file mode 100644
index 0000000000000..436ccd1d37f7d
--- /dev/null
+++ b/libc/src/math/generic/fmodbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmodbf16 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/fmodbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmodbf16, (bfloat16 x, bfloat16 y)) {
+  return fputil::generic::FMod<bfloat16, uint16_t>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index e40972ea9a879..07c36f424a0c3 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -377,6 +377,22 @@ add_fp_unittest(
     -lpthread
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  NO_RUN_POSTBUILD
+  NEED_MPFR
+  SUITE
+    libc_math_exhaustive_tests
+  SRCS
+    fmodbf16_test.cpp
+  DEPENDS
+    .exhaustive_test
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+  LINK_LIBRARIES
+    -lpthread
+)
+
 add_fp_unittest(
   coshf_test
   NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/fmodbf16_test.cpp b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..5c0fd7d12bd19
--- /dev/null
+++ b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
@@ -0,0 +1,42 @@
+//===-- Exhaustive test for fmodbf16 --------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+using LlvmLibcFmodf16ExhaustiveTest =
+    LlvmLibcBinaryOpExhaustiveMathTest<bfloat16, mpfr::Operation::Fmod,
+                                       LIBC_NAMESPACE::fmodbf16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostivePositiveRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostiveNegativeRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativePositiveRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativeNegativeRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 226ef2ee71866..7cf463596022f 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4503,6 +4503,23 @@ add_fp_unittest(
   UNIT_TEST_ONLY
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    fmodbf16_test.cpp
+  HDRS
+    FModTest.h
+  DEPENDS
+    libc.hdr.fenv_macros
+    libc.src.errno.errno
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fenv_impl
+  UNIT_TEST_ONLY
+)
+
 add_fp_unittest(
   coshf_test
   SUITE
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index 04cbc659ece5d..c72cf93cb7128 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -36,7 +36,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
   void testSpecialNumbers(FModFunc f) {
     // fmod (+0, y) == +0 for y != 0.
-    TEST_SPECIAL(zero, T(3.0), zero, false, 0);
+    // FIXME: raises FE_INEXACT for bfloat16
+    // TEST_SPECIAL(zero, T(3.0), zero, false, 0);
     TEST_SPECIAL(zero, min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, -min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, min_normal, zero, false, 0);
@@ -45,7 +46,7 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(zero, -max_normal, zero, false, 0);
 
     // fmod (-0, y) == -0 for y != 0.
-    TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
+    // TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);
@@ -99,21 +100,21 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
     // fmod (x, -inf) == x for x not infinite.
     TEST_SPECIAL(zero, neg_inf, zero, false, 0);
     TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
     TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
 
     TEST_SPECIAL(zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);
@@ -132,8 +133,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0);
-    TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
-    TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
     TEST_SPECIAL(aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);
@@ -165,10 +166,10 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID);
     TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID);
 
-    TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
-    TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
 
     TEST_SPECIAL(max_normal, max_normal, zero, false, 0);
     TEST_SPECIAL(max_normal, -max_normal, zero, false, 0);
diff --git a/libc/test/src/math/smoke/fmodbf16_test.cpp b/libc/test/src/math/smoke/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..8f30941c89b6a
--- /dev/null
+++ b/libc/test/src/math/smoke/fmodbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmodbf16 --------------------------------------------===//
+//
+// 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 "FModTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+
+LIST_FMOD_TESTS(bfloat16, LIBC_NAMESPACE::fmodbf16)

@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

@llvm/pr-subscribers-libc

Author: Krishna Pandey (krishna2803)

Changes

This PR adds fmodbf16 basic math function for BFloat16 type along with the tests.


Full diff: https://github.com/llvm/llvm-project/pull/155575.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/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/docs/headers/math/index.rst (+1-1)
  • (modified) libc/src/math/CMakeLists.txt (+1)
  • (added) libc/src/math/fmodbf16.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+14)
  • (added) libc/src/math/generic/fmodbf16.cpp (+21)
  • (modified) libc/test/src/math/exhaustive/CMakeLists.txt (+16)
  • (added) libc/test/src/math/exhaustive/fmodbf16_test.cpp (+42)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+17)
  • (modified) libc/test/src/math/smoke/FModTest.h (+13-12)
  • (added) libc/test/src/math/smoke/fmodbf16_test.cpp (+14)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 637be4f19d5b7..782769e2c0ef9 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -788,6 +788,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 19aedb0a8677d..f112c2b36fdf3 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index cfbb598cbe4bf..53e5914b9ec32 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 26e97d8993039..b4e210ad3ae0b 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -621,6 +621,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 0556a6f7a4715..95392f7718849 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -264,6 +264,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 8817972480aac..737d1bb3ac61c 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -647,6 +647,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index db762ed5c74d6..c06d63576bbd3 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -649,6 +649,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 0a2ebfa3f8720..9aeb6a7361cd5 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -876,6 +876,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index ea1c5c0558272..591c57d479dc2 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -491,6 +491,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index d5180b77c3af0..b2cd511506607 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -894,6 +894,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c64db2cc3548f..d5db2606a9887 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -927,6 +927,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 9f825bdf657e9..2da48c32d0af3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -337,6 +337,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index a707b37894afc..4520f56137bd7 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -175,7 +175,7 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fminimum_num     | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.12.9              | F.10.9.5                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                |                        | 7.12.10.1              | F.10.7.1                   |
+| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.10.1              | F.10.7.1                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fmul             | N/A              | |check|         | |check|                | N/A                  | |check|\*              | N/A                    | 7.12.14.3              | F.10.11                    |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 4b325f773b35f..d2fba849f7e27 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -306,6 +306,7 @@ add_math_entrypoint_object(fmodf)
 add_math_entrypoint_object(fmodl)
 add_math_entrypoint_object(fmodf16)
 add_math_entrypoint_object(fmodf128)
+add_math_entrypoint_object(fmodbf16)
 
 add_math_entrypoint_object(frexp)
 add_math_entrypoint_object(frexpf)
diff --git a/libc/src/math/fmodbf16.h b/libc/src/math/fmodbf16.h
new file mode 100644
index 0000000000000..176dbcc83eda0
--- /dev/null
+++ b/libc/src/math/fmodbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmodbf16 ----------------------*- 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_FMODBF16_H
+#define LLVM_LIBC_SRC_MATH_FMODBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmodbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMODBF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b1fcbf356777a..b9ef116e3dbb9 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4015,6 +4015,20 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.generic.fmod
 )
 
+add_entrypoint_object(
+  fmodbf16
+  SRCS
+    fmodbf16.cpp
+  HDRS
+    ../fmodbf16.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.generic.fmod
+)
+
 add_entrypoint_object(
   fromfp
   SRCS
diff --git a/libc/src/math/generic/fmodbf16.cpp b/libc/src/math/generic/fmodbf16.cpp
new file mode 100644
index 0000000000000..436ccd1d37f7d
--- /dev/null
+++ b/libc/src/math/generic/fmodbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmodbf16 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/fmodbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmodbf16, (bfloat16 x, bfloat16 y)) {
+  return fputil::generic::FMod<bfloat16, uint16_t>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index e40972ea9a879..07c36f424a0c3 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -377,6 +377,22 @@ add_fp_unittest(
     -lpthread
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  NO_RUN_POSTBUILD
+  NEED_MPFR
+  SUITE
+    libc_math_exhaustive_tests
+  SRCS
+    fmodbf16_test.cpp
+  DEPENDS
+    .exhaustive_test
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+  LINK_LIBRARIES
+    -lpthread
+)
+
 add_fp_unittest(
   coshf_test
   NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/fmodbf16_test.cpp b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..5c0fd7d12bd19
--- /dev/null
+++ b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
@@ -0,0 +1,42 @@
+//===-- Exhaustive test for fmodbf16 --------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+using LlvmLibcFmodf16ExhaustiveTest =
+    LlvmLibcBinaryOpExhaustiveMathTest<bfloat16, mpfr::Operation::Fmod,
+                                       LIBC_NAMESPACE::fmodbf16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostivePositiveRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostiveNegativeRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativePositiveRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativeNegativeRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 226ef2ee71866..7cf463596022f 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4503,6 +4503,23 @@ add_fp_unittest(
   UNIT_TEST_ONLY
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    fmodbf16_test.cpp
+  HDRS
+    FModTest.h
+  DEPENDS
+    libc.hdr.fenv_macros
+    libc.src.errno.errno
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fenv_impl
+  UNIT_TEST_ONLY
+)
+
 add_fp_unittest(
   coshf_test
   SUITE
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index 04cbc659ece5d..c72cf93cb7128 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -36,7 +36,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
   void testSpecialNumbers(FModFunc f) {
     // fmod (+0, y) == +0 for y != 0.
-    TEST_SPECIAL(zero, T(3.0), zero, false, 0);
+    // FIXME: raises FE_INEXACT for bfloat16
+    // TEST_SPECIAL(zero, T(3.0), zero, false, 0);
     TEST_SPECIAL(zero, min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, -min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, min_normal, zero, false, 0);
@@ -45,7 +46,7 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(zero, -max_normal, zero, false, 0);
 
     // fmod (-0, y) == -0 for y != 0.
-    TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
+    // TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);
@@ -99,21 +100,21 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
     // fmod (x, -inf) == x for x not infinite.
     TEST_SPECIAL(zero, neg_inf, zero, false, 0);
     TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
     TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
 
     TEST_SPECIAL(zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);
@@ -132,8 +133,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0);
-    TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
-    TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
     TEST_SPECIAL(aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);
@@ -165,10 +166,10 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID);
     TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID);
 
-    TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
-    TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
 
     TEST_SPECIAL(max_normal, max_normal, zero, false, 0);
     TEST_SPECIAL(max_normal, -max_normal, zero, false, 0);
diff --git a/libc/test/src/math/smoke/fmodbf16_test.cpp b/libc/test/src/math/smoke/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..8f30941c89b6a
--- /dev/null
+++ b/libc/test/src/math/smoke/fmodbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmodbf16 --------------------------------------------===//
+//
+// 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 "FModTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+
+LIST_FMOD_TESTS(bfloat16, LIBC_NAMESPACE::fmodbf16)

@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

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

Author: Krishna Pandey (krishna2803)

Changes

This PR adds fmodbf16 basic math function for BFloat16 type along with the tests.


Full diff: https://github.com/llvm/llvm-project/pull/155575.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/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/docs/headers/math/index.rst (+1-1)
  • (modified) libc/src/math/CMakeLists.txt (+1)
  • (added) libc/src/math/fmodbf16.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+14)
  • (added) libc/src/math/generic/fmodbf16.cpp (+21)
  • (modified) libc/test/src/math/exhaustive/CMakeLists.txt (+16)
  • (added) libc/test/src/math/exhaustive/fmodbf16_test.cpp (+42)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+17)
  • (modified) libc/test/src/math/smoke/FModTest.h (+13-12)
  • (added) libc/test/src/math/smoke/fmodbf16_test.cpp (+14)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 637be4f19d5b7..782769e2c0ef9 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -788,6 +788,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 19aedb0a8677d..f112c2b36fdf3 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index cfbb598cbe4bf..53e5914b9ec32 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -791,6 +791,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 26e97d8993039..b4e210ad3ae0b 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -621,6 +621,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 0556a6f7a4715..95392f7718849 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -264,6 +264,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 8817972480aac..737d1bb3ac61c 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -647,6 +647,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index db762ed5c74d6..c06d63576bbd3 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -649,6 +649,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 0a2ebfa3f8720..9aeb6a7361cd5 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -876,6 +876,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index ea1c5c0558272..591c57d479dc2 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -491,6 +491,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index d5180b77c3af0..b2cd511506607 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -894,6 +894,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c64db2cc3548f..d5db2606a9887 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -927,6 +927,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 9f825bdf657e9..2da48c32d0af3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -337,6 +337,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.fminimum_magbf16
   libc.src.math.fminimum_mag_numbf16
   libc.src.math.fminimum_numbf16
+  libc.src.math.fmodbf16
   libc.src.math.frexpbf16
   libc.src.math.fromfpbf16
   libc.src.math.fromfpxbf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index a707b37894afc..4520f56137bd7 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -175,7 +175,7 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fminimum_num     | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.12.9              | F.10.9.5                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
-| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                |                        | 7.12.10.1              | F.10.7.1                   |
+| fmod             | |check|          | |check|         | |check|                | |check|              | |check|                | |check|                | 7.12.10.1              | F.10.7.1                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
 | fmul             | N/A              | |check|         | |check|                | N/A                  | |check|\*              | N/A                    | 7.12.14.3              | F.10.11                    |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 4b325f773b35f..d2fba849f7e27 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -306,6 +306,7 @@ add_math_entrypoint_object(fmodf)
 add_math_entrypoint_object(fmodl)
 add_math_entrypoint_object(fmodf16)
 add_math_entrypoint_object(fmodf128)
+add_math_entrypoint_object(fmodbf16)
 
 add_math_entrypoint_object(frexp)
 add_math_entrypoint_object(frexpf)
diff --git a/libc/src/math/fmodbf16.h b/libc/src/math/fmodbf16.h
new file mode 100644
index 0000000000000..176dbcc83eda0
--- /dev/null
+++ b/libc/src/math/fmodbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmodbf16 ----------------------*- 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_FMODBF16_H
+#define LLVM_LIBC_SRC_MATH_FMODBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmodbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMODBF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b1fcbf356777a..b9ef116e3dbb9 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4015,6 +4015,20 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.generic.fmod
 )
 
+add_entrypoint_object(
+  fmodbf16
+  SRCS
+    fmodbf16.cpp
+  HDRS
+    ../fmodbf16.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.generic.fmod
+)
+
 add_entrypoint_object(
   fromfp
   SRCS
diff --git a/libc/src/math/generic/fmodbf16.cpp b/libc/src/math/generic/fmodbf16.cpp
new file mode 100644
index 0000000000000..436ccd1d37f7d
--- /dev/null
+++ b/libc/src/math/generic/fmodbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmodbf16 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/fmodbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmodbf16, (bfloat16 x, bfloat16 y)) {
+  return fputil::generic::FMod<bfloat16, uint16_t>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index e40972ea9a879..07c36f424a0c3 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -377,6 +377,22 @@ add_fp_unittest(
     -lpthread
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  NO_RUN_POSTBUILD
+  NEED_MPFR
+  SUITE
+    libc_math_exhaustive_tests
+  SRCS
+    fmodbf16_test.cpp
+  DEPENDS
+    .exhaustive_test
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+  LINK_LIBRARIES
+    -lpthread
+)
+
 add_fp_unittest(
   coshf_test
   NO_RUN_POSTBUILD
diff --git a/libc/test/src/math/exhaustive/fmodbf16_test.cpp b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..5c0fd7d12bd19
--- /dev/null
+++ b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
@@ -0,0 +1,42 @@
+//===-- Exhaustive test for fmodbf16 --------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+using LlvmLibcFmodf16ExhaustiveTest =
+    LlvmLibcBinaryOpExhaustiveMathTest<bfloat16, mpfr::Operation::Fmod,
+                                       LIBC_NAMESPACE::fmodbf16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostivePositiveRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostiveNegativeRange) {
+  test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativePositiveRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativeNegativeRange) {
+  test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 226ef2ee71866..7cf463596022f 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4503,6 +4503,23 @@ add_fp_unittest(
   UNIT_TEST_ONLY
 )
 
+add_fp_unittest(
+  fmodbf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    fmodbf16_test.cpp
+  HDRS
+    FModTest.h
+  DEPENDS
+    libc.hdr.fenv_macros
+    libc.src.errno.errno
+    libc.src.math.fmodbf16
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fenv_impl
+  UNIT_TEST_ONLY
+)
+
 add_fp_unittest(
   coshf_test
   SUITE
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index 04cbc659ece5d..c72cf93cb7128 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -36,7 +36,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
   void testSpecialNumbers(FModFunc f) {
     // fmod (+0, y) == +0 for y != 0.
-    TEST_SPECIAL(zero, T(3.0), zero, false, 0);
+    // FIXME: raises FE_INEXACT for bfloat16
+    // TEST_SPECIAL(zero, T(3.0), zero, false, 0);
     TEST_SPECIAL(zero, min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, -min_denormal, zero, false, 0);
     TEST_SPECIAL(zero, min_normal, zero, false, 0);
@@ -45,7 +46,7 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(zero, -max_normal, zero, false, 0);
 
     // fmod (-0, y) == -0 for y != 0.
-    TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
+    // TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);
     TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);
@@ -99,21 +100,21 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
     // fmod (x, -inf) == x for x not infinite.
     TEST_SPECIAL(zero, neg_inf, zero, false, 0);
     TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
     TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);
     TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);
     TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);
-    TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
+    // TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
 
     TEST_SPECIAL(zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
-    TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
+    // TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, aNaN, aNaN, false, 0);
     TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0);
     TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);
@@ -132,8 +133,8 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0);
-    TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
-    TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
+    // TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
     TEST_SPECIAL(aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0);
     TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);
@@ -165,10 +166,10 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID);
     TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID);
 
-    TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
-    TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
-    TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
+    // TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
+    // TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
 
     TEST_SPECIAL(max_normal, max_normal, zero, false, 0);
     TEST_SPECIAL(max_normal, -max_normal, zero, false, 0);
diff --git a/libc/test/src/math/smoke/fmodbf16_test.cpp b/libc/test/src/math/smoke/fmodbf16_test.cpp
new file mode 100644
index 0000000000000..8f30941c89b6a
--- /dev/null
+++ b/libc/test/src/math/smoke/fmodbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmodbf16 --------------------------------------------===//
+//
+// 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 "FModTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+
+LIST_FMOD_TESTS(bfloat16, LIBC_NAMESPACE::fmodbf16)

Signed-off-by: Krishna Pandey <[email protected]>
Signed-off-by: Krishna Pandey <[email protected]>
Comment on lines 178 to 181
TEST_SPECIAL(six_halves, two_quaters, two, false, 0);
TEST_SPECIAL(neg_six_halves, two_quaters, neg_two, false, 0);
TEST_SPECIAL(six_halves, neg_two_quaters, two, false, 0);
TEST_SPECIAL(neg_six_halves, neg_two_quaters, neg_two, false, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would revert this unless it's needed for some reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean removing these tests or reverting these changes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just these changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are needed because T(6.5), raises FP_INEXACT exception

// [...]
TEST_SPECIAL(T(6.5), two_quaters, two, false, 0);
// [...]
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcFmodTest.SpecialNumbers
/home/krishna/projects/llvm-project/libc/test/src/math/smoke/FModTest.h:178: FAILURE
      Expected: __llvm_libc_22_0_0_git::fputil::test_except( static_cast<int>((0x20 | 0x04 | 0x10 | 0x08 | 0x01))) & ((0) ? (0) : static_cast<int>((0x20 | 0x04 | 0x10 | 0x08 | 0x01)))
      Which is: 32
To be equal to: (0)
      Which is: 0
[  FAILED  ] LlvmLibcFmodTest.SpecialNumbers

Same is true for all other T(...) casts

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, maybe val_6_5, val_neg_2_25, etc, would still be more readable. But it's a nit at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in d8c8870

Base automatically changed from users/krishna2803/scalbnbf16 to main August 28, 2025 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants