[libc-commits] [libc] [libc] Make ffma functions constexpr (PR #226872)
via libc-commits
libc-commits at lists.llvm.org
Sun Sep 27 19:50:47 PDT 2026
https://github.com/user1342234 created https://github.com/llvm/llvm-project/pull/226872
Make ffma functions constexpr along with tests
Notes:
`libc/src/__support/FPUtil/generic/FMA.h` - The new check supports more types such as emulated `Float128`
>From b1061a4a768313d6073f81e7939182826d6063c8 Mon Sep 17 00:00:00 2001
From: abu <ayywarepremium at gmail.com>
Date: Sun, 27 Sep 2026 18:08:03 -0700
Subject: [PATCH 1/3] Check zero bits without using operator==
---
libc/src/__support/FPUtil/generic/FMA.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index f08f92d8febc0a..795d8227b4b1e6 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -29,10 +29,10 @@ namespace fputil {
namespace generic {
template <typename OutType, typename InType>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
- cpp::is_floating_point_v<InType> &&
- sizeof(OutType) <= sizeof(InType),
- 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>
fma(InType x, InType y, InType z);
// TODO(lntue): Implement fmaf that is correctly rounded to all rounding modes.
@@ -105,10 +105,10 @@ 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> &&
- cpp::is_floating_point_v<InType> &&
- sizeof(OutType) <= sizeof(InType),
- 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>
fma(InType x, InType y, InType z) {
using OutFPBits = FPBits<OutType>;
using OutStorageType = typename OutFPBits::StorageType;
@@ -157,7 +157,7 @@ fma(InType x, InType y, InType z) {
}
}
- if (LIBC_UNLIKELY(x == 0 || y == 0 || z == 0))
+ if (LIBC_UNLIKELY(x_bits.is_zero() || y_bits.is_zero() || z_bits.is_zero()))
return cast<OutType>(x * y + z);
int x_exp = 0;
>From c5c462dae0445c5449f12e2f8221979d63d5be31 Mon Sep 17 00:00:00 2001
From: abu <ayywarepremium at gmail.com>
Date: Sun, 27 Sep 2026 18:10:39 -0700
Subject: [PATCH 2/3] Add constexpr support
---
libc/src/__support/FPUtil/FMA.h | 2 +-
libc/src/__support/math/ffma.h | 2 +-
libc/src/__support/math/ffmaf128.h | 2 +-
libc/src/__support/math/ffmal.h | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/FMA.h b/libc/src/__support/FPUtil/FMA.h
index 2cafb4c0974e31..189232190acf03 100644
--- a/libc/src/__support/FPUtil/FMA.h
+++ b/libc/src/__support/FPUtil/FMA.h
@@ -19,7 +19,7 @@ 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);
}
diff --git a/libc/src/__support/math/ffma.h b/libc/src/__support/math/ffma.h
index 64431e8bec4070..d924921a906c04 100644
--- a/libc/src/__support/math/ffma.h
+++ b/libc/src/__support/math/ffma.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float ffma(double x, double y, double z) {
+LIBC_INLINE constexpr float ffma(double x, double y, double z) {
return fputil::fma<float>(x, y, z);
}
diff --git a/libc/src/__support/math/ffmaf128.h b/libc/src/__support/math/ffmaf128.h
index 5714421a60ba94..f3e2ec3c8c2f12 100644
--- a/libc/src/__support/math/ffmaf128.h
+++ b/libc/src/__support/math/ffmaf128.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float ffmaf128(float128 x, float128 y, float128 z) {
+LIBC_INLINE constexpr float ffmaf128(float128 x, float128 y, float128 z) {
return fputil::fma<float>(x, y, z);
}
diff --git a/libc/src/__support/math/ffmal.h b/libc/src/__support/math/ffmal.h
index b03c45ea25cf2d..c5328fb62d5e9c 100644
--- a/libc/src/__support/math/ffmal.h
+++ b/libc/src/__support/math/ffmal.h
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float ffmal(long double x, long double y, long double z) {
+LIBC_INLINE constexpr float ffmal(long double x, long double y, long double z) {
return fputil::fma<float>(x, y, z);
}
>From 9535fc27203c2ee8018ead7ed27c2b9eee74a11c Mon Sep 17 00:00:00 2001
From: abu <ayywarepremium at gmail.com>
Date: Sun, 27 Sep 2026 18:11:02 -0700
Subject: [PATCH 3/3] Add shared constexpr tests
---
libc/test/shared/shared_math_constexpr_test.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index ec7f99a9ff40c0..9848b5f2a4d68b 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -31,6 +31,7 @@ static_assert(1.0 == LIBC_NAMESPACE::shared::fabs(-1.0));
static_assert(1.0 == LIBC_NAMESPACE::shared::fdim(1.0, 0.0));
static_assert(bfloat16(0.0) == LIBC_NAMESPACE::shared::bf16sub(0.0, 0.0));
static_assert(0.0f == LIBC_NAMESPACE::shared::fdiv(0.0, 1.0));
+static_assert(0.0f == LIBC_NAMESPACE::shared::ffma(0.0, 0.0, 0.0));
static_assert(1.0 == LIBC_NAMESPACE::shared::floor(1.2));
static_assert(2.0 == LIBC_NAMESPACE::shared::fmaximum_mag_num(1.0, 2.0));
static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
@@ -316,6 +317,7 @@ static_assert(1.0L == LIBC_NAMESPACE::shared::fabsl(-1.0L));
static_assert(0.0f == LIBC_NAMESPACE::shared::faddl(0.0L, 0.0L));
static_assert(1.0L == LIBC_NAMESPACE::shared::fdiml(1.0L, 0.0L));
static_assert(0.0f == LIBC_NAMESPACE::shared::fdivl(0.0L, 1.0L));
+static_assert(0.0f == LIBC_NAMESPACE::shared::ffmal(0.0L, 0.0, 0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::floorl(0.0L));
static_assert(bfloat16(0.0) == LIBC_NAMESPACE::shared::bf16subl(0.0L, 0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::sqrtl(0.0L));
@@ -473,6 +475,9 @@ static_assert(0.0f ==
LIBC_NAMESPACE::shared::faddf128(float128(0.0), float128(0.0)));
static_assert(0.0f ==
LIBC_NAMESPACE::shared::fdivf128(float128(0.0), float128(1.0)));
+static_assert(0.0f == LIBC_NAMESPACE::shared::ffmaf128(float128(0.0),
+ float128(0.0),
+ float128(0.0)));
static_assert(bfloat16(0.0) ==
LIBC_NAMESPACE::shared::bf16subf128(float128(0.0),
float128(0.0)));
More information about the libc-commits
mailing list