[libc-commits] [libc] [llvm] [libc][math] change bf16fmal to be header-only and constexpr-compat (PR #181666)
via libc-commits
libc-commits at lists.llvm.org
Mon Feb 16 06:03:18 PST 2026
https://github.com/Serosh-commits updated https://github.com/llvm/llvm-project/pull/181666
>From 85d4c4615979e2ce33217f94526545dbc62a5e7f Mon Sep 17 00:00:00 2001
From: Serosh-commits <janmejayapanda400 at gmail.com>
Date: Mon, 16 Feb 2026 19:13:42 +0530
Subject: [PATCH] [libc][math] Refactor bf16fmal to be header-only and
constexpr-compatible
---
libc/shared/math/bf16fmal.h | 24 +++++++++++
libc/src/__support/FPUtil/BasicOperations.h | 42 +++++++++----------
libc/src/__support/FPUtil/FMA.h | 6 +--
libc/src/__support/FPUtil/bfloat16.h | 20 ++++-----
.../__support/FPUtil/comparison_operations.h | 10 ++---
libc/src/__support/FPUtil/generic/FMA.h | 8 ++--
libc/src/__support/FPUtil/generic/add_sub.h | 6 +--
libc/src/__support/FPUtil/generic/div.h | 2 +-
libc/src/__support/FPUtil/generic/mul.h | 2 +-
libc/src/__support/math/CMakeLists.txt | 11 +++++
libc/src/__support/math/bf16fmal.h | 27 ++++++++++++
libc/src/math/bf16fmal.h | 1 +
libc/src/math/generic/CMakeLists.txt | 4 +-
libc/src/math/generic/bf16fmal.cpp | 8 ++--
libc/test/src/math/smoke/bf16fmal_test.cpp | 2 +
.../llvm-project-overlay/libc/BUILD.bazel | 19 +++++++++
16 files changed, 136 insertions(+), 56 deletions(-)
create mode 100644 libc/shared/math/bf16fmal.h
create mode 100644 libc/src/__support/math/bf16fmal.h
diff --git a/libc/shared/math/bf16fmal.h b/libc/shared/math/bf16fmal.h
new file mode 100644
index 0000000000000..db3e246ccf26f
--- /dev/null
+++ b/libc/shared/math/bf16fmal.h
@@ -0,0 +1,24 @@
+//===-- Shared bf16fmal function --------------------------------*- 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_SHARED_MATH_BF16FMAL_H
+#define LLVM_LIBC_SHARED_MATH_BF16FMAL_H
+
+#include "src/__support/math/bf16fmal.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace shared {
+
+using math::bf16fmal;
+
+} // namespace shared
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_BF16FMAL_H
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index ca7be6676630a..f57336c44a6b9 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -26,14 +26,14 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T abs(T x) {
+LIBC_INLINE constexpr T abs(T x) {
return FPBits<T>(x).abs().get_val();
}
namespace internal {
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> max(T x, T y) {
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T> max(T x, T y) {
FPBits<T> x_bits(x);
FPBits<T> y_bits(y);
@@ -47,11 +47,11 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> max(T x, T y) {
#ifdef LIBC_TYPES_HAS_FLOAT16
#if defined(__LIBC_USE_BUILTIN_FMAXF16_FMINF16)
-template <> LIBC_INLINE float16 max(float16 x, float16 y) {
+template <> LIBC_INLINE constexpr float16 max(float16 x, float16 y) {
return __builtin_fmaxf16(x, y);
}
#elif !defined(LIBC_TARGET_ARCH_IS_AARCH64)
-template <> LIBC_INLINE float16 max(float16 x, float16 y) {
+template <> LIBC_INLINE constexpr float16 max(float16 x, float16 y) {
FPBits<float16> x_bits(x);
FPBits<float16> y_bits(y);
@@ -63,17 +63,17 @@ template <> LIBC_INLINE float16 max(float16 x, float16 y) {
#endif // LIBC_TYPES_HAS_FLOAT16
#if defined(__LIBC_USE_BUILTIN_FMAX_FMIN) && !defined(LIBC_TARGET_ARCH_IS_X86)
-template <> LIBC_INLINE float max(float x, float y) {
+template <> LIBC_INLINE constexpr float max(float x, float y) {
return __builtin_fmaxf(x, y);
}
-template <> LIBC_INLINE double max(double x, double y) {
+template <> LIBC_INLINE constexpr double max(double x, double y) {
return __builtin_fmax(x, y);
}
#endif
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> min(T x, T y) {
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T> min(T x, T y) {
FPBits<T> x_bits(x);
FPBits<T> y_bits(y);
@@ -87,11 +87,11 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> min(T x, T y) {
#ifdef LIBC_TYPES_HAS_FLOAT16
#if defined(__LIBC_USE_BUILTIN_FMAXF16_FMINF16)
-template <> LIBC_INLINE float16 min(float16 x, float16 y) {
+template <> LIBC_INLINE constexpr float16 min(float16 x, float16 y) {
return __builtin_fminf16(x, y);
}
#elif !defined(LIBC_TARGET_ARCH_IS_AARCH64)
-template <> LIBC_INLINE float16 min(float16 x, float16 y) {
+template <> LIBC_INLINE constexpr float16 min(float16 x, float16 y) {
FPBits<float16> x_bits(x);
FPBits<float16> y_bits(y);
@@ -103,11 +103,11 @@ template <> LIBC_INLINE float16 min(float16 x, float16 y) {
#endif // LIBC_TYPES_HAS_FLOAT16
#if defined(__LIBC_USE_BUILTIN_FMAX_FMIN) && !defined(LIBC_TARGET_ARCH_IS_X86)
-template <> LIBC_INLINE float min(float x, float y) {
+template <> LIBC_INLINE constexpr float min(float x, float y) {
return __builtin_fminf(x, y);
}
-template <> LIBC_INLINE double min(double x, double y) {
+template <> LIBC_INLINE constexpr double min(double x, double y) {
return __builtin_fmin(x, y);
}
#endif
@@ -115,7 +115,7 @@ template <> LIBC_INLINE double min(double x, double y) {
} // namespace internal
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmin(T x, T y) {
+LIBC_INLINE constexpr T fmin(T x, T y) {
const FPBits<T> bitx(x), bity(y);
if (bitx.is_nan())
@@ -126,7 +126,7 @@ LIBC_INLINE T fmin(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmax(T x, T y) {
+LIBC_INLINE constexpr T fmax(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_nan())
@@ -137,7 +137,7 @@ LIBC_INLINE T fmax(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmaximum(T x, T y) {
+LIBC_INLINE constexpr T fmaximum(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_nan())
@@ -148,7 +148,7 @@ LIBC_INLINE T fmaximum(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fminimum(T x, T y) {
+LIBC_INLINE constexpr T fminimum(T x, T y) {
const FPBits<T> bitx(x), bity(y);
if (bitx.is_nan())
@@ -159,7 +159,7 @@ LIBC_INLINE T fminimum(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmaximum_num(T x, T y) {
+LIBC_INLINE constexpr T fmaximum_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
fputil::raise_except_if_required(FE_INVALID);
@@ -174,7 +174,7 @@ LIBC_INLINE T fmaximum_num(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fminimum_num(T x, T y) {
+LIBC_INLINE constexpr T fminimum_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
fputil::raise_except_if_required(FE_INVALID);
@@ -189,7 +189,7 @@ LIBC_INLINE T fminimum_num(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmaximum_mag(T x, T y) {
+LIBC_INLINE constexpr T fmaximum_mag(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (abs(x) > abs(y))
@@ -200,7 +200,7 @@ LIBC_INLINE T fmaximum_mag(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fminimum_mag(T x, T y) {
+LIBC_INLINE constexpr T fminimum_mag(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (abs(x) < abs(y))
@@ -211,7 +211,7 @@ LIBC_INLINE T fminimum_mag(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fmaximum_mag_num(T x, T y) {
+LIBC_INLINE constexpr T fmaximum_mag_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (abs(x) > abs(y))
@@ -222,7 +222,7 @@ LIBC_INLINE T fmaximum_mag_num(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fminimum_mag_num(T x, T y) {
+LIBC_INLINE constexpr T fminimum_mag_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (abs(x) < abs(y))
diff --git a/libc/src/__support/FPUtil/FMA.h b/libc/src/__support/FPUtil/FMA.h
index 2cafb4c0974e3..873647f3566de 100644
--- a/libc/src/__support/FPUtil/FMA.h
+++ b/libc/src/__support/FPUtil/FMA.h
@@ -19,14 +19,14 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil {
template <typename OutType, typename InType>
-LIBC_INLINE OutType fma(InType x, InType y, InType z) {
+LIBC_INLINE constexpr OutType fma(InType x, InType y, InType z) {
return generic::fma<OutType>(x, y, z);
}
#ifdef LIBC_TARGET_CPU_HAS_FMA
#ifdef LIBC_TARGET_CPU_HAS_FMA_FLOAT
-template <> LIBC_INLINE float fma(float x, float y, float z) {
+template <> LIBC_INLINE constexpr float fma(float x, float y, float z) {
#if __has_builtin(__builtin_elementwise_fma)
return __builtin_elementwise_fma(x, y, z);
#else
@@ -36,7 +36,7 @@ template <> LIBC_INLINE float fma(float x, float y, float z) {
#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-template <> LIBC_INLINE double fma(double x, double y, double z) {
+template <> LIBC_INLINE constexpr double fma(double x, double y, double z) {
#if __has_builtin(__builtin_elementwise_fma)
return __builtin_elementwise_fma(x, y, z);
#else
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 13e151208567d..bd38e81e3a85a 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -68,27 +68,27 @@ struct BFloat16 {
return static_cast<T>(static_cast<float>(*this));
}
- LIBC_INLINE bool operator==(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator==(BFloat16 other) const {
return fputil::equals(*this, other);
}
- LIBC_INLINE bool operator!=(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator!=(BFloat16 other) const {
return !fputil::equals(*this, other);
}
- LIBC_INLINE bool operator<(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator<(BFloat16 other) const {
return fputil::less_than(*this, other);
}
- LIBC_INLINE bool operator<=(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator<=(BFloat16 other) const {
return fputil::less_than_or_equals(*this, other);
}
- LIBC_INLINE bool operator>(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator>(BFloat16 other) const {
return fputil::greater_than(*this, other);
}
- LIBC_INLINE bool operator>=(BFloat16 other) const {
+ LIBC_INLINE constexpr bool operator>=(BFloat16 other) const {
return fputil::greater_than_or_equals(*this, other);
}
@@ -98,19 +98,19 @@ struct BFloat16 {
return result.get_val();
}
- LIBC_INLINE BFloat16 operator+(BFloat16 other) const {
+ LIBC_INLINE constexpr BFloat16 operator+(BFloat16 other) const {
return fputil::generic::add<BFloat16>(*this, other);
}
- LIBC_INLINE BFloat16 operator-(BFloat16 other) const {
+ LIBC_INLINE constexpr BFloat16 operator-(BFloat16 other) const {
return fputil::generic::sub<BFloat16>(*this, other);
}
- LIBC_INLINE BFloat16 operator*(BFloat16 other) const {
+ LIBC_INLINE constexpr BFloat16 operator*(BFloat16 other) const {
return fputil::generic::mul<bfloat16>(*this, other);
}
- LIBC_INLINE BFloat16 operator/(BFloat16 other) const {
+ LIBC_INLINE constexpr BFloat16 operator/(BFloat16 other) const {
return fputil::generic::div<bfloat16>(*this, other);
}
}; // struct BFloat16
diff --git a/libc/src/__support/FPUtil/comparison_operations.h b/libc/src/__support/FPUtil/comparison_operations.h
index ff62ce085513b..71c0d996341da 100644
--- a/libc/src/__support/FPUtil/comparison_operations.h
+++ b/libc/src/__support/FPUtil/comparison_operations.h
@@ -26,7 +26,7 @@ namespace fputil {
// (iii) -inf != +inf
// 3. Any comparison with NaN returns false
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> equals(T x,
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> equals(T x,
T y) {
using FPBits = FPBits<T>;
FPBits x_bits(x);
@@ -52,7 +52,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> equals(T x,
// 2. x < +inf (x != +inf)
// 3. Any comparison with NaN return false
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> less_than(T x,
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> less_than(T x,
T y) {
using FPBits = FPBits<T>;
FPBits x_bits(x);
@@ -87,7 +87,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> less_than(T x,
// Implements compareSignalingGreater predicate
// x < y => y > x
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
greater_than(T x, T y) {
return less_than(y, x);
}
@@ -95,7 +95,7 @@ greater_than(T x, T y) {
// Implements compareSignalingLessEqual predicate
// x <= y => (x < y) || (x == y)
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
less_than_or_equals(T x, T y) {
return less_than(x, y) || equals(x, y);
}
@@ -103,7 +103,7 @@ less_than_or_equals(T x, T y) {
// Implements compareSignalingGreaterEqual predicate
// x >= y => (x > y) || (x == y) => (y < x) || (x == y)
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
greater_than_or_equals(T x, T y) {
return less_than(y, x) || equals(x, y);
}
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index bec312e44b1b1..dd102c3fb929b 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -29,7 +29,7 @@ namespace fputil {
namespace generic {
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
@@ -38,7 +38,7 @@ fma(InType x, InType y, InType z);
// TODO(lntue): Implement fmaf that is correctly rounded to all rounding modes.
// The implementation below only is only correct for the default rounding mode,
// round-to-nearest tie-to-even.
-template <> LIBC_INLINE float fma<float>(float x, float y, float z) {
+template <> LIBC_INLINE constexpr float fma<float>(float x, float y, float z) {
// Product is exact.
double prod = static_cast<double>(x) * static_cast<double>(y);
double z_d = static_cast<double>(z);
@@ -90,7 +90,7 @@ namespace internal {
// Extract the sticky bits and shift the `mantissa` to the right by
// `shift_length`.
template <typename T>
-LIBC_INLINE cpp::enable_if_t<is_unsigned_integral_or_big_int_v<T>, bool>
+LIBC_INLINE constexpr cpp::enable_if_t<is_unsigned_integral_or_big_int_v<T>, bool>
shift_mantissa(int shift_length, T &mant) {
if (shift_length >= cpp::numeric_limits<T>::digits) {
mant = 0;
@@ -105,7 +105,7 @@ shift_mantissa(int shift_length, T &mant) {
} // namespace internal
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 9f3ecff0eb233..ea046dc89aacd 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -27,7 +27,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil::generic {
template <bool IsSub, typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
@@ -201,7 +201,7 @@ add_or_sub(InType x, InType y) {
}
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
@@ -210,7 +210,7 @@ add(InType x, InType y) {
}
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
diff --git a/libc/src/__support/FPUtil/generic/div.h b/libc/src/__support/FPUtil/generic/div.h
index bf7d0b7112ca9..993ac165670ee 100644
--- a/libc/src/__support/FPUtil/generic/div.h
+++ b/libc/src/__support/FPUtil/generic/div.h
@@ -26,7 +26,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil::generic {
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
diff --git a/libc/src/__support/FPUtil/generic/mul.h b/libc/src/__support/FPUtil/generic/mul.h
index 20d9a77792762..1c75503cd536f 100644
--- a/libc/src/__support/FPUtil/generic/mul.h
+++ b/libc/src/__support/FPUtil/generic/mul.h
@@ -25,7 +25,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil::generic {
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
cpp::is_floating_point_v<InType> &&
sizeof(OutType) <= sizeof(InType),
OutType>
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index aaab78c01a891..fc8f10badb31c 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -814,6 +814,17 @@ add_header_library(
libc.include.llvm-libc-macros.float16_macros
)
+add_header_library(
+ bf16fmal
+ HDRS
+ bf16fmal.h
+ DEPENDS
+ libc.src.__support.macros.config
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.types
+)
+
add_header_library(
ilogb
HDRS
diff --git a/libc/src/__support/math/bf16fmal.h b/libc/src/__support/math/bf16fmal.h
new file mode 100644
index 0000000000000..70e8a070461d8
--- /dev/null
+++ b/libc/src/__support/math/bf16fmal.h
@@ -0,0 +1,27 @@
+//===-- 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___SUPPORT_MATH_BF16FMAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_BF16FMAL_H
+
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+LIBC_INLINE constexpr bfloat16 bf16fmal(long double x, long double y, long double z) {
+ return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_BF16FMAL_H
diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h
index b92f17b7ee8d6..69338c5d2ada6 100644
--- a/libc/src/math/bf16fmal.h
+++ b/libc/src/math/bf16fmal.h
@@ -11,6 +11,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
+#include "src/__support/math/bf16fmal.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 75b51b4587bea..6c67fc67b1b0c 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -5263,10 +5263,8 @@ add_entrypoint_object(
../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
+ libc.src.__support.math.bf16fmal
)
add_entrypoint_object(
diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp
index f31ec6904760b..408b5b8765498 100644
--- a/libc/src/math/generic/bf16fmal.cpp
+++ b/libc/src/math/generic/bf16fmal.cpp
@@ -7,16 +7,14 @@
//===----------------------------------------------------------------------===//
#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"
+#include "src/__support/math/bf16fmal.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);
+ return math::bf16fmal(x, y, z);
}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/smoke/bf16fmal_test.cpp b/libc/test/src/math/smoke/bf16fmal_test.cpp
index 4c45e2c64312d..17498ffe10158 100644
--- a/libc/test/src/math/smoke/bf16fmal_test.cpp
+++ b/libc/test/src/math/smoke/bf16fmal_test.cpp
@@ -12,3 +12,5 @@
#include "src/math/bf16fmal.h"
LIST_NARROWING_FMA_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16fmal)
+
+static_assert(LIBC_NAMESPACE::math::bf16fmal(1.0l, 2.0l, 3.0l) == bfloat16(5.0f));
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 608180b90e87b..01f8c1a6344de 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3006,6 +3006,18 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_bf16fmal",
+ hdrs = ["src/__support/math/bf16fmal.h"],
+ deps = [
+ ":__support_common",
+ ":__support_fputil_fma",
+ ":__support_fputil_bfloat16",
+ ":__support_macros_config",
+ ":__support_macros_properties_types",
+ ],
+)
+
libc_support_library(
name = "__support_math_ffma",
hdrs = ["src/__support/math/ffma.h"],
@@ -4716,6 +4728,13 @@ libc_math_function(
additional_deps = [":__support_math_f16fmal"],
)
+libc_math_function(
+ name = "bf16fmal",
+ additional_deps = [
+ ":__support_math_bf16fmal",
+ ],
+)
+
libc_math_function(name = "f16mul")
libc_math_function(name = "f16mulf")
More information about the libc-commits
mailing list