Skip to content

[libc][math][c++23] Add bf16fma{,f,l,f128} math functions - #153231

Merged
krishna2803 merged 5 commits into
llvm:mainfrom
krishna2803:bf16fma
Aug 13, 2025
Merged

[libc][math][c++23] Add bf16fma{,f,l,f128} math functions#153231
krishna2803 merged 5 commits into
llvm:mainfrom
krishna2803:bf16fma

Conversation

@krishna2803

Copy link
Copy Markdown
Contributor

This PR adds the following basic math functions for BFloat16 type along with the tests:

  • bf16fma
  • bf16fmaf
  • bf16fmal
  • bf16fmaf128

Signed-off-by: Krishna Pandey <kpandey81930@gmail.com>
…MPFRUtils

Signed-off-by: Krishna Pandey <kpandey81930@gmail.com>
Signed-off-by: Krishna Pandey <kpandey81930@gmail.com>
Signed-off-by: Krishna Pandey <kpandey81930@gmail.com>
Signed-off-by: Krishna Pandey <kpandey81930@gmail.com>
@llvmbot

llvmbot commented Aug 12, 2025

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-libc

@llvm/pr-subscribers-backend-amdgpu

Author: Krishna Pandey (krishna2803)

Changes

This PR adds the following basic math functions for BFloat16 type along with the tests:

  • bf16fma
  • bf16fmaf
  • bf16fmal
  • bf16fmaf128

Patch is 29.34 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153231.diff

33 Files Affected:

  • (modified) libc/config/baremetal/aarch64/entrypoints.txt (+4)
  • (modified) libc/config/baremetal/arm/entrypoints.txt (+4)
  • (modified) libc/config/baremetal/riscv/entrypoints.txt (+4)
  • (modified) libc/config/darwin/aarch64/entrypoints.txt (+3)
  • (modified) libc/config/darwin/x86_64/entrypoints.txt (+3)
  • (modified) libc/config/gpu/amdgpu/entrypoints.txt (+3)
  • (modified) libc/config/gpu/nvptx/entrypoints.txt (+3)
  • (modified) libc/config/linux/aarch64/entrypoints.txt (+4)
  • (modified) libc/config/linux/arm/entrypoints.txt (+3)
  • (modified) libc/config/linux/riscv/entrypoints.txt (+4)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+4)
  • (modified) libc/config/windows/entrypoints.txt (+3)
  • (modified) libc/src/math/CMakeLists.txt (+5)
  • (added) libc/src/math/bf16fma.h (+21)
  • (added) libc/src/math/bf16fmaf.h (+21)
  • (added) libc/src/math/bf16fmaf128.h (+21)
  • (added) libc/src/math/bf16fmal.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+60-4)
  • (added) libc/src/math/generic/bf16fma.cpp (+21)
  • (added) libc/src/math/generic/bf16fmaf.cpp (+21)
  • (added) libc/src/math/generic/bf16fmaf128.cpp (+22)
  • (added) libc/src/math/generic/bf16fmal.cpp (+22)
  • (modified) libc/test/src/math/CMakeLists.txt (+64)
  • (added) libc/test/src/math/bf16fma_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmaf128_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmaf_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmal_test.cpp (+14)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+60)
  • (added) libc/test/src/math/smoke/bf16fma_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmaf128_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmaf_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmal_test.cpp (+14)
  • (modified) libc/utils/MPFRWrapper/MPFRUtils.cpp (+36)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 007d64d3fcd7c..00fd4675e7f09 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -763,6 +763,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -792,6 +795,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 6c1f52a8f1ca2..9a7800c0f9b86 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -766,6 +766,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -795,6 +798,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index d1412762333de..34b400bdc52c5 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -766,6 +766,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -795,6 +798,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 57c09f0725048..d45ec3589c97e 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -596,6 +596,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 9b207fd734e99..1e12e9e167b73 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -239,6 +239,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 8981190cfe1bc..4b6f3337036aa 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -622,6 +622,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index dc23742652783..d24cc740d4234 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -623,6 +623,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 5f687525271ee..e71dc2ee0d02f 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -850,6 +850,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -879,6 +882,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 47689a2234aca..ec01030c77d4f 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -466,6 +466,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index b9efadc7deef2..54ea983d64839 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -869,6 +869,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -898,6 +901,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 458cb5999e403..1ee10e6d3cade 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -901,6 +901,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -930,6 +933,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 00104a31af44e..37a2ee286010a 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -312,6 +312,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2cf5ae5eab726..8db5901afa9c0 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -584,6 +584,11 @@ add_math_entrypoint_object(bf16divf)
 add_math_entrypoint_object(bf16divl)
 add_math_entrypoint_object(bf16divf128)
 
+add_math_entrypoint_object(bf16fma)
+add_math_entrypoint_object(bf16fmaf)
+add_math_entrypoint_object(bf16fmal)
+add_math_entrypoint_object(bf16fmaf128)
+
 add_math_entrypoint_object(bf16mul)
 add_math_entrypoint_object(bf16mulf)
 add_math_entrypoint_object(bf16mull)
diff --git a/libc/src/math/bf16fma.h b/libc/src/math/bf16fma.h
new file mode 100644
index 0000000000000..aa54956ef4783
--- /dev/null
+++ b/libc/src/math/bf16fma.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fma -----------------------*- 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_BF16FMA_H
+#define LLVM_LIBC_SRC_MATH_BF16FMA_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fma(double x, double y, double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMA_H
diff --git a/libc/src/math/bf16fmaf.h b/libc/src/math/bf16fmaf.h
new file mode 100644
index 0000000000000..e8582bd6dff5f
--- /dev/null
+++ b/libc/src/math/bf16fmaf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf ----------------------*- 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_BF16FMAF_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf(float x, float y, float z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF_H
diff --git a/libc/src/math/bf16fmaf128.h b/libc/src/math/bf16fmaf128.h
new file mode 100644
index 0000000000000..4215e54c82ff5
--- /dev/null
+++ b/libc/src/math/bf16fmaf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf128 -------------------*- 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_BF16FMAF128_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf128(float128 x, float128 y, float128 z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF128_H
diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h
new file mode 100644
index 0000000000000..b92f17b7ee8d6
--- /dev/null
+++ b/libc/src/math/bf16fmal.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmal ----------------------*- 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_BF16FMAL_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmal(long double x, long double y, long double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAL_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 70e5bf682ed9f..ca2d07cc06189 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -5106,15 +5106,57 @@ add_entrypoint_object(
 )
 
 add_entrypoint_object(
-  bf16sub
+  bf16fma
   SRCS
-    bf16sub.cpp
+    bf16fma.cpp
   HDRS
-    ../bf16sub.h
+    ../bf16fma.h
   DEPENDS
     libc.src.__support.common
     libc.src.__support.FPUtil.bfloat16
-    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmaf
+  SRCS
+    bf16fmaf.cpp
+  HDRS
+    ../bf16fmaf.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmal
+  SRCS
+    bf16fmal.cpp
+  HDRS
+    ../bf16fmal.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmaf128
+  SRCS
+    bf16fmaf128.cpp
+  HDRS
+    ../bf16fmaf128.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
     libc.src.__support.macros.config
     libc.src.__support.macros.properties.types
 )
@@ -5175,6 +5217,20 @@ add_entrypoint_object(
     libc.src.__support.macros.properties.types
 )
 
+add_entrypoint_object(
+  bf16sub
+  SRCS
+    bf16sub.cpp
+  HDRS
+    ../bf16sub.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
 add_entrypoint_object(
   bf16subf
   SRCS
diff --git a/libc/src/math/generic/bf16fma.cpp b/libc/src/math/generic/bf16fma.cpp
new file mode 100644
index 0000000000000..0f0fe8658dde0
--- /dev/null
+++ b/libc/src/math/generic/bf16fma.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fma 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/bf16fma.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fma, (double x, double y, double z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf.cpp b/libc/src/math/generic/bf16fmaf.cpp
new file mode 100644
index 0000000000000..739691cc50117
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fmaf 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/bf16fmaf.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf, (float x, float y, float z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf128.cpp b/libc/src/math/generic/bf16fmaf128.cpp
new file mode 100644
index 0000000000000..a29a0b0b27276
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf128.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmaf128 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/bf16fmaf128.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf128,
+                   (float128 x, float128 y, float128 z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp
new file mode 100644
index 0000000000000..f31ec6904760b
--- /dev/null
+++ b/libc/src/math/generic/bf16fmal.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmal 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/bf16fmal.h"
+
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmal,
+                   (long double x, long double y, long double z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 85dddfb88d7e6..11bbf670c98dd 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -3084,6 +3084,70 @@ add_fp_unittest(
     libc.src.__support.FPUtil.bfloat16
 )
 
+add_fp_unittest(
+  bf16fma_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fma_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fma
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmaf_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmaf_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmaf
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmal_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmal_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmal
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmaf128_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmaf128_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmaf128
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
 add_fp_unittest(
   bf16mul_test
   NEED_MPFR
diff --git a/libc/test/src/math/bf16fma_test.cpp b/libc/test/src/math/bf16fma_test.cpp
new file mode 100644
index 0000000000000..81c73a0cb6947
--- /dev/null
+++ b/libc/test/src/math/bf16fma_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fma ---------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fma.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma)
diff --git a/libc/test/src/math/bf16fmaf128_test.cpp b/libc/test/src/math/bf16fmaf128_test.cpp
new file mode 100644
index 0000000000000..dd8f4735c3497
--- /dev/null
+++ b/libc/test/src/math/bf16fmaf128_test.cpp
@@ -...
[truncated]

@llvmbot

llvmbot commented Aug 12, 2025

Copy link
Copy Markdown
Member

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

Author: Krishna Pandey (krishna2803)

Changes

This PR adds the following basic math functions for BFloat16 type along with the tests:

  • bf16fma
  • bf16fmaf
  • bf16fmal
  • bf16fmaf128

Patch is 29.34 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153231.diff

33 Files Affected:

  • (modified) libc/config/baremetal/aarch64/entrypoints.txt (+4)
  • (modified) libc/config/baremetal/arm/entrypoints.txt (+4)
  • (modified) libc/config/baremetal/riscv/entrypoints.txt (+4)
  • (modified) libc/config/darwin/aarch64/entrypoints.txt (+3)
  • (modified) libc/config/darwin/x86_64/entrypoints.txt (+3)
  • (modified) libc/config/gpu/amdgpu/entrypoints.txt (+3)
  • (modified) libc/config/gpu/nvptx/entrypoints.txt (+3)
  • (modified) libc/config/linux/aarch64/entrypoints.txt (+4)
  • (modified) libc/config/linux/arm/entrypoints.txt (+3)
  • (modified) libc/config/linux/riscv/entrypoints.txt (+4)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+4)
  • (modified) libc/config/windows/entrypoints.txt (+3)
  • (modified) libc/src/math/CMakeLists.txt (+5)
  • (added) libc/src/math/bf16fma.h (+21)
  • (added) libc/src/math/bf16fmaf.h (+21)
  • (added) libc/src/math/bf16fmaf128.h (+21)
  • (added) libc/src/math/bf16fmal.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+60-4)
  • (added) libc/src/math/generic/bf16fma.cpp (+21)
  • (added) libc/src/math/generic/bf16fmaf.cpp (+21)
  • (added) libc/src/math/generic/bf16fmaf128.cpp (+22)
  • (added) libc/src/math/generic/bf16fmal.cpp (+22)
  • (modified) libc/test/src/math/CMakeLists.txt (+64)
  • (added) libc/test/src/math/bf16fma_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmaf128_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmaf_test.cpp (+14)
  • (added) libc/test/src/math/bf16fmal_test.cpp (+14)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+60)
  • (added) libc/test/src/math/smoke/bf16fma_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmaf128_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmaf_test.cpp (+14)
  • (added) libc/test/src/math/smoke/bf16fmal_test.cpp (+14)
  • (modified) libc/utils/MPFRWrapper/MPFRUtils.cpp (+36)
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 007d64d3fcd7c..00fd4675e7f09 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -763,6 +763,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -792,6 +795,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 6c1f52a8f1ca2..9a7800c0f9b86 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -766,6 +766,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -795,6 +798,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index d1412762333de..34b400bdc52c5 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -766,6 +766,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -795,6 +798,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 57c09f0725048..d45ec3589c97e 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -596,6 +596,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 9b207fd734e99..1e12e9e167b73 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -239,6 +239,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 8981190cfe1bc..4b6f3337036aa 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -622,6 +622,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index dc23742652783..d24cc740d4234 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -623,6 +623,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 5f687525271ee..e71dc2ee0d02f 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -850,6 +850,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -879,6 +882,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 47689a2234aca..ec01030c77d4f 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -466,6 +466,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index b9efadc7deef2..54ea983d64839 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -869,6 +869,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -898,6 +901,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 458cb5999e403..1ee10e6d3cade 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -901,6 +901,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
@@ -930,6 +933,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     # math.h C++23 mixed bfloat16 and _Float128 entrypoints
     libc.src.math.bf16addf128
     libc.src.math.bf16divf128
+    libc.src.math.bf16fmaf128
     libc.src.math.bf16mulf128
     libc.src.math.bf16subf128
   )
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 00104a31af44e..37a2ee286010a 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -312,6 +312,9 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
   libc.src.math.bf16div
   libc.src.math.bf16divf
   libc.src.math.bf16divl
+  libc.src.math.bf16fma
+  libc.src.math.bf16fmaf
+  libc.src.math.bf16fmal
   libc.src.math.bf16mul
   libc.src.math.bf16mulf
   libc.src.math.bf16mull
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2cf5ae5eab726..8db5901afa9c0 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -584,6 +584,11 @@ add_math_entrypoint_object(bf16divf)
 add_math_entrypoint_object(bf16divl)
 add_math_entrypoint_object(bf16divf128)
 
+add_math_entrypoint_object(bf16fma)
+add_math_entrypoint_object(bf16fmaf)
+add_math_entrypoint_object(bf16fmal)
+add_math_entrypoint_object(bf16fmaf128)
+
 add_math_entrypoint_object(bf16mul)
 add_math_entrypoint_object(bf16mulf)
 add_math_entrypoint_object(bf16mull)
diff --git a/libc/src/math/bf16fma.h b/libc/src/math/bf16fma.h
new file mode 100644
index 0000000000000..aa54956ef4783
--- /dev/null
+++ b/libc/src/math/bf16fma.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fma -----------------------*- 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_BF16FMA_H
+#define LLVM_LIBC_SRC_MATH_BF16FMA_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fma(double x, double y, double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMA_H
diff --git a/libc/src/math/bf16fmaf.h b/libc/src/math/bf16fmaf.h
new file mode 100644
index 0000000000000..e8582bd6dff5f
--- /dev/null
+++ b/libc/src/math/bf16fmaf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf ----------------------*- 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_BF16FMAF_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf(float x, float y, float z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF_H
diff --git a/libc/src/math/bf16fmaf128.h b/libc/src/math/bf16fmaf128.h
new file mode 100644
index 0000000000000..4215e54c82ff5
--- /dev/null
+++ b/libc/src/math/bf16fmaf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf128 -------------------*- 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_BF16FMAF128_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf128(float128 x, float128 y, float128 z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF128_H
diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h
new file mode 100644
index 0000000000000..b92f17b7ee8d6
--- /dev/null
+++ b/libc/src/math/bf16fmal.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmal ----------------------*- 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_BF16FMAL_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmal(long double x, long double y, long double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAL_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 70e5bf682ed9f..ca2d07cc06189 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -5106,15 +5106,57 @@ add_entrypoint_object(
 )
 
 add_entrypoint_object(
-  bf16sub
+  bf16fma
   SRCS
-    bf16sub.cpp
+    bf16fma.cpp
   HDRS
-    ../bf16sub.h
+    ../bf16fma.h
   DEPENDS
     libc.src.__support.common
     libc.src.__support.FPUtil.bfloat16
-    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmaf
+  SRCS
+    bf16fmaf.cpp
+  HDRS
+    ../bf16fmaf.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmal
+  SRCS
+    bf16fmal.cpp
+  HDRS
+    ../bf16fmal.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  bf16fmaf128
+  SRCS
+    bf16fmaf128.cpp
+  HDRS
+    ../bf16fmaf128.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.fma
     libc.src.__support.macros.config
     libc.src.__support.macros.properties.types
 )
@@ -5175,6 +5217,20 @@ add_entrypoint_object(
     libc.src.__support.macros.properties.types
 )
 
+add_entrypoint_object(
+  bf16sub
+  SRCS
+    bf16sub.cpp
+  HDRS
+    ../bf16sub.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.FPUtil.bfloat16
+    libc.src.__support.FPUtil.generic.add_sub
+    libc.src.__support.macros.config
+    libc.src.__support.macros.properties.types
+)
+
 add_entrypoint_object(
   bf16subf
   SRCS
diff --git a/libc/src/math/generic/bf16fma.cpp b/libc/src/math/generic/bf16fma.cpp
new file mode 100644
index 0000000000000..0f0fe8658dde0
--- /dev/null
+++ b/libc/src/math/generic/bf16fma.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fma 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/bf16fma.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fma, (double x, double y, double z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf.cpp b/libc/src/math/generic/bf16fmaf.cpp
new file mode 100644
index 0000000000000..739691cc50117
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fmaf 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/bf16fmaf.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf, (float x, float y, float z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf128.cpp b/libc/src/math/generic/bf16fmaf128.cpp
new file mode 100644
index 0000000000000..a29a0b0b27276
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf128.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmaf128 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/bf16fmaf128.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf128,
+                   (float128 x, float128 y, float128 z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp
new file mode 100644
index 0000000000000..f31ec6904760b
--- /dev/null
+++ b/libc/src/math/generic/bf16fmal.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmal 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/bf16fmal.h"
+
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmal,
+                   (long double x, long double y, long double z)) {
+  return fputil::fma<bfloat16>(x, y, z);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 85dddfb88d7e6..11bbf670c98dd 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -3084,6 +3084,70 @@ add_fp_unittest(
     libc.src.__support.FPUtil.bfloat16
 )
 
+add_fp_unittest(
+  bf16fma_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fma_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fma
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmaf_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmaf_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmaf
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmal_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmal_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmal
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+  bf16fmaf128_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    bf16fmaf128_test.cpp
+  HDRS
+    FmaTest.h
+  DEPENDS
+    libc.src.math.bf16fmaf128
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.__support.FPUtil.bfloat16
+)
+
 add_fp_unittest(
   bf16mul_test
   NEED_MPFR
diff --git a/libc/test/src/math/bf16fma_test.cpp b/libc/test/src/math/bf16fma_test.cpp
new file mode 100644
index 0000000000000..81c73a0cb6947
--- /dev/null
+++ b/libc/test/src/math/bf16fma_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fma ---------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fma.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma)
diff --git a/libc/test/src/math/bf16fmaf128_test.cpp b/libc/test/src/math/bf16fmaf128_test.cpp
new file mode 100644
index 0000000000000..dd8f4735c3497
--- /dev/null
+++ b/libc/test/src/math/bf16fmaf128_test.cpp
@@ -...
[truncated]

@krishna2803
krishna2803 merged commit 41c9510 into llvm:main Aug 13, 2025
23 checks passed
@krishna2803
krishna2803 deleted the bf16fma branch August 15, 2025 22:55
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.

3 participants