[libc-commits] [libc] [libc][math] Qualify fdim funtions to constexpr (PR #194137)
Kiriti Ponduri via libc-commits
libc-commits at lists.llvm.org
Sat Apr 25 13:51:04 PDT 2026
https://github.com/udaykiriti updated https://github.com/llvm/llvm-project/pull/194137
>From ebe53a36c341478b9754b832a9fdfd316cadc870 Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Sat, 25 Apr 2026 16:39:26 +0530
Subject: [PATCH 1/4] [libc][math] Qualify fdim funtions to constexpr
Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
---
libc/src/__support/FPUtil/BasicOperations.h | 2 +-
libc/src/__support/FPUtil/generic/add_sub.h | 52 +++++++++++++------
libc/src/__support/math/fdim.h | 4 +-
libc/src/__support/math/fdimbf16.h | 2 +-
libc/src/__support/math/fdimf.h | 4 +-
libc/src/__support/math/fdimf128.h | 2 +-
libc/src/__support/math/fdimf16.h | 4 +-
libc/src/__support/math/fdiml.h | 2 +-
libc/test/shared/CMakeLists.txt | 6 +++
.../shared/shared_math_constexpr_test.cpp | 8 +++
10 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index ca7be6676630a..92f9ea05b1dbd 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -233,7 +233,7 @@ LIBC_INLINE T fminimum_mag_num(T x, T y) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T fdim(T x, T y) {
+LIBC_INLINE T constexpr fdim(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_nan()) {
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 6777345afcd11..dec0c209e18ea 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -52,8 +52,11 @@ add_or_sub(InType x, InType y) {
if (LIBC_UNLIKELY(x_bits.is_inf_or_nan() || y_bits.is_inf_or_nan() ||
x_bits.is_zero() || y_bits.is_zero())) {
if (x_bits.is_nan() || y_bits.is_nan()) {
- if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
- raise_except_if_required(FE_INVALID);
+ if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan()) {
+ if (!__builtin_is_constant_evaluated()) {
+ raise_except_if_required(FE_INVALID);
+ }
+ }
if (x_bits.is_quiet_nan()) {
InStorageType x_payload = x_bits.get_mantissa();
@@ -77,7 +80,9 @@ add_or_sub(InType x, InType y) {
if (x_bits.is_inf()) {
if (y_bits.is_inf()) {
if (!is_effectively_add) {
- raise_except_if_required(FE_INVALID);
+ if (!__builtin_is_constant_evaluated()) {
+ raise_except_if_required(FE_INVALID);
+ }
return OutFPBits::quiet_nan().get_val();
}
@@ -98,11 +103,15 @@ add_or_sub(InType x, InType y) {
if (y_bits.is_zero()) {
if (is_effectively_add)
return OutFPBits::zero(x_bits.sign()).get_val();
- switch (quick_get_round()) {
- case FE_DOWNWARD:
- return OutFPBits::zero(Sign::NEG).get_val();
- default:
+ if (__builtin_is_constant_evaluated()) {
return OutFPBits::zero(Sign::POS).get_val();
+ } else {
+ switch (quick_get_round()) {
+ case FE_DOWNWARD:
+ return OutFPBits::zero(Sign::NEG).get_val();
+ default:
+ return OutFPBits::zero(Sign::POS).get_val();
+ }
}
}
@@ -117,10 +126,17 @@ add_or_sub(InType x, InType y) {
// volatile prevents Clang from converting tmp to OutType and then
// immediately back to InType before negating it, resulting in double
// rounding.
- volatile InType tmp = y;
- if constexpr (IsSub)
- tmp = -tmp;
- return cast<OutType>(tmp);
+ if (__builtin_is_constant_evaluated()) {
+ InType tmp = y;
+ if constexpr (IsSub)
+ tmp = -tmp;
+ return cast<OutType>(tmp);
+ } else {
+ volatile InType tmp = y;
+ if constexpr (IsSub)
+ tmp = -tmp;
+ return cast<OutType>(tmp);
+ }
}
}
@@ -132,11 +148,15 @@ add_or_sub(InType x, InType y) {
InType y_abs = y_bits.abs().get_val();
if (x_abs == y_abs && !is_effectively_add) {
- switch (quick_get_round()) {
- case FE_DOWNWARD:
- return OutFPBits::zero(Sign::NEG).get_val();
- default:
+ if (__builtin_is_constant_evaluated()) {
return OutFPBits::zero(Sign::POS).get_val();
+ } else {
+ switch (quick_get_round()) {
+ case FE_DOWNWARD:
+ return OutFPBits::zero(Sign::NEG).get_val();
+ default:
+ return OutFPBits::zero(Sign::POS).get_val();
+ }
}
}
@@ -155,7 +175,7 @@ add_or_sub(InType x, InType y) {
InFPBits max_bits(cpp::max(x_abs, y_abs));
InFPBits min_bits(cpp::min(x_abs, y_abs));
- InStorageType result_mant;
+ InStorageType result_mant = 0;
if (max_bits.is_subnormal()) {
// min_bits must be subnormal too.
diff --git a/libc/src/__support/math/fdim.h b/libc/src/__support/math/fdim.h
index 6b6def814a28a..24e5425237295 100644
--- a/libc/src/__support/math/fdim.h
+++ b/libc/src/__support/math/fdim.h
@@ -15,7 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE double fdim(double x, double y) { return fputil::fdim(x, y); }
+LIBC_INLINE constexpr double fdim(double x, double y) {
+ return fputil::fdim(x, y);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/fdimbf16.h b/libc/src/__support/math/fdimbf16.h
index 473a326b8c114..265f771648a17 100644
--- a/libc/src/__support/math/fdimbf16.h
+++ b/libc/src/__support/math/fdimbf16.h
@@ -16,7 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE bfloat16 fdimbf16(bfloat16 x, bfloat16 y) {
+LIBC_INLINE constexpr bfloat16 fdimbf16(bfloat16 x, bfloat16 y) {
return fputil::fdim(x, y);
}
diff --git a/libc/src/__support/math/fdimf.h b/libc/src/__support/math/fdimf.h
index d837b5200de38..39e3050c9f311 100644
--- a/libc/src/__support/math/fdimf.h
+++ b/libc/src/__support/math/fdimf.h
@@ -15,7 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float fdimf(float x, float y) { return fputil::fdim(x, y); }
+LIBC_INLINE constexpr float fdimf(float x, float y) {
+ return fputil::fdim(x, y);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/fdimf128.h b/libc/src/__support/math/fdimf128.h
index 02e4b821f2a4b..2537070633257 100644
--- a/libc/src/__support/math/fdimf128.h
+++ b/libc/src/__support/math/fdimf128.h
@@ -19,7 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float128 fdimf128(float128 x, float128 y) {
+LIBC_INLINE constexpr float128 fdimf128(float128 x, float128 y) {
return fputil::fdim(x, y);
}
diff --git a/libc/src/__support/math/fdimf16.h b/libc/src/__support/math/fdimf16.h
index b92ae6eae8c59..0a5142cafb8f9 100644
--- a/libc/src/__support/math/fdimf16.h
+++ b/libc/src/__support/math/fdimf16.h
@@ -19,7 +19,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float16 fdimf16(float16 x, float16 y) { return fputil::fdim(x, y); }
+LIBC_INLINE constexpr float16 fdimf16(float16 x, float16 y) {
+ return fputil::fdim(x, y);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/fdiml.h b/libc/src/__support/math/fdiml.h
index bc765951d4a4d..285c61910577e 100644
--- a/libc/src/__support/math/fdiml.h
+++ b/libc/src/__support/math/fdiml.h
@@ -15,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE long double fdiml(long double x, long double y) {
+LIBC_INLINE constexpr long double fdiml(long double x, long double y) {
return fputil::fdim(x, y);
}
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index ea40834cea495..d062ed3b8e003 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -294,6 +294,12 @@ add_fp_unittest(
libc.src.__support.math.copysignl
libc.src.__support.math.dmulf128
libc.src.__support.math.dmull
+ libc.src.__support.math.fdim
+ libc.src.__support.math.fdimbf16
+ libc.src.__support.math.fdimf
+ libc.src.__support.math.fdimf128
+ libc.src.__support.math.fdimf16
+ libc.src.__support.math.fdiml
libc.src.__support.math.floor
libc.src.__support.math.floorbf16
libc.src.__support.math.floorf
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index e42bb2bde857f..683aac1a605ef 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -17,6 +17,7 @@
static_assert(0.0 == LIBC_NAMESPACE::shared::ceil(0.0));
static_assert(0.0 == LIBC_NAMESPACE::shared::copysign(0.0, 0.0));
+static_assert(1.0 == LIBC_NAMESPACE::shared::fdim(1.0, 0.0));
static_assert(1.0 == LIBC_NAMESPACE::shared::floor(1.2));
static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
@@ -26,6 +27,7 @@ static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
static_assert(0.0f == LIBC_NAMESPACE::shared::ceilf(0.0f));
static_assert(0.0f == LIBC_NAMESPACE::shared::copysignf(0.0f, 0.0f));
+static_assert(1.0f == LIBC_NAMESPACE::shared::fdimf(1.0f, 0.0f));
static_assert(0.0f == LIBC_NAMESPACE::shared::floorf(0.0f));
//===----------------------------------------------------------------------===//
@@ -36,6 +38,7 @@ static_assert(0.0f == LIBC_NAMESPACE::shared::floorf(0.0f));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::ceilf16(0.0f16));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::copysignf16(0.0f16, 0.0f16));
+static_assert(1.0f16 == LIBC_NAMESPACE::shared::fdimf16(1.0f16, 0.0f16));
static_assert(3.0f16 == LIBC_NAMESPACE::shared::floorf16(3.7f16));
#endif // LIBC_TYPES_HAS_FLOAT16
@@ -50,6 +53,7 @@ static_assert(3.0f16 == LIBC_NAMESPACE::shared::floorf16(3.7f16));
static_assert(0.0L == LIBC_NAMESPACE::shared::ceill(0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::copysignl(0.0L, 0.0L));
static_assert(0.0 == LIBC_NAMESPACE::shared::dmull(0.0L, 1.0L));
+static_assert(1.0L == LIBC_NAMESPACE::shared::fdiml(1.0L, 0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::floorl(0.0L));
#endif
@@ -66,6 +70,8 @@ static_assert(float128(0.0) ==
float128(0.0)));
static_assert(0.0 ==
LIBC_NAMESPACE::shared::dmulf128(float128(0.0), float128(1.0)));
+static_assert(float128(1.0) ==
+ LIBC_NAMESPACE::shared::fdimf128(float128(1.0), float128(0.0)));
static_assert(float128(0.0) ==
LIBC_NAMESPACE::shared::floorf128(float128(0.0)));
@@ -80,6 +86,8 @@ static_assert(bfloat16(0.0) == LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
static_assert(bfloat16(0.0) ==
LIBC_NAMESPACE::shared::copysignbf16(bfloat16(0.0),
bfloat16(0.0)));
+static_assert(bfloat16(1.0) ==
+ LIBC_NAMESPACE::shared::fdimbf16(bfloat16(1.0), bfloat16(0.0)));
static_assert(bfloat16(0.0) ==
LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0f)));
static_assert(bfloat16(0.0) ==
>From 13b56f2de1f2973af652fd2f1c35a37debc06450 Mon Sep 17 00:00:00 2001
From: Kiriti Ponduri <123718855+udaykiriti at users.noreply.github.com>
Date: Sun, 26 Apr 2026 02:20:27 +0530
Subject: [PATCH 2/4] Update libc/src/__support/FPUtil/generic/add_sub.h
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix at users.noreply.github.com>
---
libc/src/__support/FPUtil/generic/add_sub.h | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 61aecff7431b0..dfce0a7ce11c5 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -52,11 +52,8 @@ add_or_sub(InType x, InType y) {
if (LIBC_UNLIKELY(x_bits.is_inf_or_nan() || y_bits.is_inf_or_nan() ||
x_bits.is_zero() || y_bits.is_zero())) {
if (x_bits.is_nan() || y_bits.is_nan()) {
- if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan()) {
- if (!__builtin_is_constant_evaluated()) {
- raise_except_if_required(FE_INVALID);
- }
- }
+ if (!cpp::is_constant_evaluated() && (x_bits.is_signaling_nan() || y_bits.is_signaling_nan()))
+ raise_except_if_required(FE_INVALID);
if (x_bits.is_quiet_nan()) {
InStorageType x_payload = x_bits.get_mantissa();
>From 6a66b99f6300eff1ec0de55448c4ae1e8102cdb4 Mon Sep 17 00:00:00 2001
From: Kiriti Ponduri <123718855+udaykiriti at users.noreply.github.com>
Date: Sun, 26 Apr 2026 02:20:45 +0530
Subject: [PATCH 3/4] Update libc/src/__support/FPUtil/generic/add_sub.h
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix at users.noreply.github.com>
---
libc/src/__support/FPUtil/generic/add_sub.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index dfce0a7ce11c5..727ea6bcad85f 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -77,9 +77,8 @@ add_or_sub(InType x, InType y) {
if (x_bits.is_inf()) {
if (y_bits.is_inf()) {
if (!is_effectively_add) {
- if (!__builtin_is_constant_evaluated()) {
+ if (!cpp::is_constant_evaluated())
raise_except_if_required(FE_INVALID);
- }
return OutFPBits::quiet_nan().get_val();
}
>From 9e02ffd6e70bcd03482c9725d7c95798ca503b0b Mon Sep 17 00:00:00 2001
From: Kiriti Ponduri <123718855+udaykiriti at users.noreply.github.com>
Date: Sun, 26 Apr 2026 02:20:55 +0530
Subject: [PATCH 4/4] Update libc/src/__support/FPUtil/generic/add_sub.h
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix at users.noreply.github.com>
---
libc/src/__support/FPUtil/generic/add_sub.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 727ea6bcad85f..850ff415797d6 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -122,7 +122,7 @@ add_or_sub(InType x, InType y) {
// volatile prevents Clang from converting tmp to OutType and then
// immediately back to InType before negating it, resulting in double
// rounding.
- if (__builtin_is_constant_evaluated()) {
+ if (cpp::is_constant_evaluated()) {
InType tmp = y;
if constexpr (IsSub)
tmp = -tmp;
More information about the libc-commits
mailing list