[llvm-branch-commits] [libc] [libc][math] Qualify ceil functions to constexpr (PR #184948)
Muhammad Bassiouni via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 5 21:15:28 PST 2026
https://github.com/bassiounix updated https://github.com/llvm/llvm-project/pull/184948
>From b6c06fd32dac427eedb6138bafed18e75115479f Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 6 Mar 2026 06:50:37 +0200
Subject: [PATCH 1/2] [libc][math] Qualify ceil functions to constexpr
---
libc/src/__support/CPP/bit.h | 10 +--
.../FPUtil/NearestIntegerOperations.h | 16 ++---
libc/src/__support/FPUtil/bfloat16.h | 22 +++----
.../__support/FPUtil/comparison_operations.h | 14 ++--
libc/src/__support/FPUtil/generic/add_sub.h | 26 ++++----
libc/src/__support/FPUtil/generic/div.h | 8 +--
libc/src/__support/FPUtil/generic/mul.h | 8 +--
libc/src/__support/FPUtil/rounding_mode.h | 10 +--
libc/src/__support/math/ceil.h | 5 +-
libc/src/__support/math/ceilbf16.h | 2 +-
libc/src/__support/math/ceilf.h | 5 +-
libc/src/__support/math/ceilf128.h | 2 +-
libc/src/__support/math/ceilf16.h | 5 +-
libc/src/__support/math/ceill.h | 14 +++-
libc/test/shared/shared_math_test.cpp | 66 +++++++++++++++++--
15 files changed, 141 insertions(+), 72 deletions(-)
diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h
index d4de6769e8637..aa340b380fd32 100644
--- a/libc/src/__support/CPP/bit.h
+++ b/libc/src/__support/CPP/bit.h
@@ -27,8 +27,9 @@ namespace cpp {
#endif
template <unsigned N>
-LIBC_INLINE static void inline_copy(const char *from, char *to) {
-#if __has_builtin(__builtin_memcpy_inline)
+LIBC_INLINE LIBC_CONSTEXPR void inline_copy(const char *from, char *to) {
+#if __has_builtin(__builtin_memcpy_inline) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
__builtin_memcpy_inline(to, from, N);
#else
for (unsigned i = 0; i < N; ++i)
@@ -39,14 +40,15 @@ LIBC_INLINE static void inline_copy(const char *from, char *to) {
// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
template <typename To, typename From>
-LIBC_INLINE static constexpr cpp::enable_if_t<
+LIBC_INLINE constexpr cpp::enable_if_t<
(sizeof(To) == sizeof(From)) &&
cpp::is_trivially_constructible<To>::value &&
cpp::is_trivially_copyable<To>::value &&
cpp::is_trivially_copyable<From>::value,
To>
bit_cast(const From &from) {
-#if __has_builtin(__builtin_bit_cast) || defined(LIBC_COMPILER_IS_MSVC)
+#if __has_builtin(__builtin_bit_cast) || defined(LIBC_COMPILER_IS_MSVC) || \
+ defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_bit_cast(To, from);
#else
To to{};
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 93166614cc12a..4637b46bc9473 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -22,7 +22,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T trunc(T x) {
+LIBC_INLINE constexpr T trunc(T x) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
@@ -52,7 +52,7 @@ LIBC_INLINE T trunc(T x) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T ceil(T x) {
+LIBC_INLINE constexpr T ceil(T x) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
@@ -95,7 +95,7 @@ LIBC_INLINE T ceil(T x) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T floor(T x) {
+LIBC_INLINE constexpr T floor(T x) {
FPBits<T> bits(x);
if (bits.is_neg()) {
return -ceil(-x);
@@ -105,7 +105,7 @@ LIBC_INLINE T floor(T x) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T round(T x) {
+LIBC_INLINE constexpr T round(T x) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
@@ -244,7 +244,7 @@ round_using_specific_rounding_mode(T x, int rnd) {
}
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
round_using_current_rounding_mode(T x) {
int rounding_mode = quick_get_round();
@@ -350,7 +350,7 @@ template <typename FloatType, typename IntType,
cpp::enable_if_t<cpp::is_floating_point_v<FloatType> &&
cpp::is_integral_v<IntType>,
int> = 0>
-LIBC_INLINE IntType rounded_float_to_signed_integer(FloatType x) {
+LIBC_INLINE constexpr IntType rounded_float_to_signed_integer(FloatType x) {
constexpr IntType INTEGER_MIN = (IntType(1) << (sizeof(IntType) * 8 - 1));
constexpr IntType INTEGER_MAX = -(INTEGER_MIN + 1);
FPBits<FloatType> bits(x);
@@ -390,7 +390,7 @@ template <typename FloatType, typename IntType,
cpp::enable_if_t<cpp::is_floating_point_v<FloatType> &&
cpp::is_integral_v<IntType>,
int> = 0>
-LIBC_INLINE IntType round_to_signed_integer(FloatType x) {
+LIBC_INLINE constexpr IntType round_to_signed_integer(FloatType x) {
return internal::rounded_float_to_signed_integer<FloatType, IntType>(
round(x));
}
@@ -399,7 +399,7 @@ template <typename FloatType, typename IntType,
cpp::enable_if_t<cpp::is_floating_point_v<FloatType> &&
cpp::is_integral_v<IntType>,
int> = 0>
-LIBC_INLINE IntType
+LIBC_INLINE constexpr IntType
round_to_signed_integer_using_current_rounding_mode(FloatType x) {
return internal::rounded_float_to_signed_integer<FloatType, IntType>(
round_using_current_rounding_mode(x));
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 7d64b441bf9b2..5c8f3b7e6c77a 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,23 +98,23 @@ 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);
}
- LIBC_INLINE BFloat16 &operator*=(const BFloat16 &other) {
+ LIBC_INLINE constexpr BFloat16 &operator*=(const BFloat16 &other) {
*this = *this * other;
return *this;
}
diff --git a/libc/src/__support/FPUtil/comparison_operations.h b/libc/src/__support/FPUtil/comparison_operations.h
index ff62ce085513b..01092b4ae6efe 100644
--- a/libc/src/__support/FPUtil/comparison_operations.h
+++ b/libc/src/__support/FPUtil/comparison_operations.h
@@ -26,8 +26,8 @@ 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,
- T y) {
+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);
FPBits y_bits(y);
@@ -52,8 +52,8 @@ 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,
- T y) {
+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);
FPBits y_bits(y);
@@ -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/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 9f3ecff0eb233..9ba3bb93228ff 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -27,10 +27,10 @@ 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> &&
- 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>
add_or_sub(InType x, InType y) {
using OutFPBits = FPBits<OutType>;
using OutStorageType = typename OutFPBits::StorageType;
@@ -175,7 +175,7 @@ add_or_sub(InType x, InType y) {
InStorageType aligned_min_mant = static_cast<InStorageType>(
min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN));
- bool aligned_min_mant_sticky;
+ bool aligned_min_mant_sticky{};
if (alignment <= GUARD_BITS_LEN)
aligned_min_mant_sticky = false;
@@ -201,19 +201,19 @@ add_or_sub(InType x, InType y) {
}
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>
add(InType x, InType y) {
return add_or_sub</*IsSub=*/false, OutType>(x, y);
}
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>
sub(InType x, InType y) {
return add_or_sub</*IsSub=*/true, OutType>(x, y);
}
diff --git a/libc/src/__support/FPUtil/generic/div.h b/libc/src/__support/FPUtil/generic/div.h
index bf7d0b7112ca9..85026bb3fd40f 100644
--- a/libc/src/__support/FPUtil/generic/div.h
+++ b/libc/src/__support/FPUtil/generic/div.h
@@ -26,10 +26,10 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil::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>
div(InType x, InType y) {
using OutFPBits = FPBits<OutType>;
using OutStorageType = typename OutFPBits::StorageType;
diff --git a/libc/src/__support/FPUtil/generic/mul.h b/libc/src/__support/FPUtil/generic/mul.h
index 20d9a77792762..22c6859946180 100644
--- a/libc/src/__support/FPUtil/generic/mul.h
+++ b/libc/src/__support/FPUtil/generic/mul.h
@@ -25,10 +25,10 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil::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>
mul(InType x, InType y) {
using OutFPBits = FPBits<OutType>;
using OutStorageType = typename OutFPBits::StorageType;
diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h
index fdc84986a4781..92061ea13e203 100644
--- a/libc/src/__support/FPUtil/rounding_mode.h
+++ b/libc/src/__support/FPUtil/rounding_mode.h
@@ -80,7 +80,7 @@ LIBC_INLINE int quick_get_round() {
} // namespace generic
-LIBC_INLINE static constexpr bool fenv_is_round_up() {
+LIBC_INLINE constexpr bool fenv_is_round_up() {
if (cpp::is_constant_evaluated()) {
return false;
} else {
@@ -88,7 +88,7 @@ LIBC_INLINE static constexpr bool fenv_is_round_up() {
}
}
-LIBC_INLINE static constexpr bool fenv_is_round_down() {
+LIBC_INLINE constexpr bool fenv_is_round_down() {
if (cpp::is_constant_evaluated()) {
return false;
} else {
@@ -96,7 +96,7 @@ LIBC_INLINE static constexpr bool fenv_is_round_down() {
}
}
-LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
+LIBC_INLINE constexpr bool fenv_is_round_to_nearest() {
if (cpp::is_constant_evaluated()) {
return true;
} else {
@@ -104,7 +104,7 @@ LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
}
}
-LIBC_INLINE static constexpr bool fenv_is_round_to_zero() {
+LIBC_INLINE constexpr bool fenv_is_round_to_zero() {
if (cpp::is_constant_evaluated()) {
return false;
} else {
@@ -113,7 +113,7 @@ LIBC_INLINE static constexpr bool fenv_is_round_to_zero() {
}
// Quick free standing get rounding mode based on the above observations.
-LIBC_INLINE static constexpr int quick_get_round() {
+LIBC_INLINE constexpr int quick_get_round() {
if (cpp::is_constant_evaluated()) {
return FE_TONEAREST;
} else {
diff --git a/libc/src/__support/math/ceil.h b/libc/src/__support/math/ceil.h
index 71b89a76c1d25..a00337a597df1 100644
--- a/libc/src/__support/math/ceil.h
+++ b/libc/src/__support/math/ceil.h
@@ -15,8 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE double ceil(double x) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
+LIBC_INLINE LIBC_CONSTEXPR double ceil(double x) {
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_ceil(x);
#else
return fputil::ceil(x);
diff --git a/libc/src/__support/math/ceilbf16.h b/libc/src/__support/math/ceilbf16.h
index bdb7dfee6a325..05d21f895efb0 100644
--- a/libc/src/__support/math/ceilbf16.h
+++ b/libc/src/__support/math/ceilbf16.h
@@ -16,7 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE bfloat16 ceilbf16(bfloat16 x) { return fputil::ceil(x); }
+LIBC_INLINE constexpr bfloat16 ceilbf16(bfloat16 x) { return fputil::ceil(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/ceilf.h b/libc/src/__support/math/ceilf.h
index 58710b9bfc126..25d1180f746df 100644
--- a/libc/src/__support/math/ceilf.h
+++ b/libc/src/__support/math/ceilf.h
@@ -15,8 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float ceilf(float x) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
+LIBC_INLINE LIBC_CONSTEXPR float ceilf(float x) {
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_ceilf(x);
#else
return fputil::ceil(x);
diff --git a/libc/src/__support/math/ceilf128.h b/libc/src/__support/math/ceilf128.h
index d717379745371..8877594d58d68 100644
--- a/libc/src/__support/math/ceilf128.h
+++ b/libc/src/__support/math/ceilf128.h
@@ -19,7 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float128 ceilf128(float128 x) { return fputil::ceil(x); }
+LIBC_INLINE constexpr float128 ceilf128(float128 x) { return fputil::ceil(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/ceilf16.h b/libc/src/__support/math/ceilf16.h
index c5a8e432b1fe6..899cab6abdda6 100644
--- a/libc/src/__support/math/ceilf16.h
+++ b/libc/src/__support/math/ceilf16.h
@@ -21,9 +21,10 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float16 ceilf16(float16 x) {
+LIBC_INLINE LIBC_CONSTEXPR float16 ceilf16(float16 x) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
- defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
+ defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return fputil::cast<float16>(__builtin_ceilf(x));
#else
return fputil::ceil(x);
diff --git a/libc/src/__support/math/ceill.h b/libc/src/__support/math/ceill.h
index 8b1287a024ccf..4cec6b8e0671f 100644
--- a/libc/src/__support/math/ceill.h
+++ b/libc/src/__support/math/ceill.h
@@ -15,7 +15,19 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE long double ceill(long double x) { return fputil::ceil(x); }
+// TODO(bassiounix): Re-enable long double tests on X86 once float80 is complete
+#if !(defined(linux) && (defined(__x86_64__) || defined(__i386__)))
+
+LIBC_INLINE constexpr long double ceill(long double x) {
+
+#else
+
+LIBC_INLINE long double ceill(long double x) {
+
+#endif
+
+ return fputil::ceil(x);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 793c06c2a7c69..aafed26dbe15a 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -8,14 +8,72 @@
#define LIBC_ENABLE_CONSTEXPR 1
+// TODO(bassiounix): Cleanup include headers once constexpr refactor is done.
+#include "shared/math/ceil.h"
+#include "shared/math/ceilbf16.h"
+#include "shared/math/ceilf.h"
+#include "shared/math/ceilf128.h"
+#include "shared/math/ceilf16.h"
+#include "shared/math/ceill.h"
#include "shared/math/log.h"
#ifdef LIBC_HAS_CONSTANT_EVALUATION
-//===-- Double Tests ------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// Double Tests
+//===----------------------------------------------------------------------===//
+static_assert(0x0p+0 == LIBC_NAMESPACE::shared::ceil(0.0));
static_assert(0x0p+0 == LIBC_NAMESPACE::shared::log(1.0));
+//===----------------------------------------------------------------------===//
+// Float Tests
+//===----------------------------------------------------------------------===//
+
+static_assert(0x0p+0f == LIBC_NAMESPACE::shared::ceilf(0.0f));
+
+//===----------------------------------------------------------------------===//
+// Float16 Tests
+//===----------------------------------------------------------------------===//
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+static_assert(0x0p+0f16 == LIBC_NAMESPACE::shared::ceilf16(0.0f16));
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+//===----------------------------------------------------------------------===//
+// Long Double Tests
+//===----------------------------------------------------------------------===//
+
+// Temporarily disable long double tests on x86 and x86_64
+// TODO(bassiounix): Re-enable long double tests on X86 once GSoC26 float80/128
+// project is complete.
+#if !(defined(linux) && (defined(__x86_64__) || defined(__i386__)))
+
+static_assert(0x0p+0L == LIBC_NAMESPACE::shared::ceill(0.0L));
+
+#endif // defined(linux) && (defined(__x86_64__) || defined(__i386__))
+
+//===----------------------------------------------------------------------===//
+// Float128 Tests
+//===----------------------------------------------------------------------===//
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+
+static_assert(float128(0x0p+0) ==
+ LIBC_NAMESPACE::shared::ceilf128(float128(0.0)));
+
+#endif // LIBC_TYPES_HAS_FLOAT128
+
+//===----------------------------------------------------------------------===//
+// BFloat16 Tests
+//===----------------------------------------------------------------------===//
+
+static_assert(bfloat16(0x0p+0) ==
+ LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
+
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
#endif // LIBC_HAS_CONSTANT_EVALUATION
@@ -130,7 +188,6 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) {
&canonicalizef16_x));
EXPECT_FP_EQ(0x0p+0f16, canonicalizef16_cx);
- EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::ceilf16(0.0f16));
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::fdimf16(0.0f16, 0.0f16));
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::floorf16(0.0f16));
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::fmaxf16(0.0f16, 0.0f16));
@@ -221,7 +278,6 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mulf(0.0f, 0.0f));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16subf(0.0f, 0.0f));
- EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::ceilf(0.0f));
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fdimf(0.0f, 0.0f));
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::floorf(0.0f));
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fmaxf(0.0f, 0.0f));
@@ -283,7 +339,6 @@ TEST(LlvmLibcSharedMathTest, AllDouble) {
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mul(0.0, 0.0));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16sub(0.0, 0.0));
- EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::ceil(0.0));
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::fadd(0.0, 0.0));
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::fdim(0.0, 0.0));
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::floor(0.0));
@@ -322,7 +377,6 @@ TEST(LlvmLibcSharedMathTest, AllLongDouble) {
EXPECT_FP_EQ(0x0p+0L, canonicalizel_cx);
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mull(0.0L, 0.0L));
- EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::ceill(0.0L));
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::faddl(0.0L, 0.0L));
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::fdiml(0.0L, 0.0L));
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::floorl(0.0L));
@@ -386,7 +440,6 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
float128(0.0), float128(0.0), float128(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mulf128(
float128(0.0), float128(0.0)));
- EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::ceilf128(float128(0.0)));
EXPECT_FP_EQ(float128(0.0),
LIBC_NAMESPACE::shared::faddf128(float128(0.0), float128(0.0)));
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::floorf128(float128(0.0)));
@@ -436,7 +489,6 @@ TEST(LlvmLibcSharedMathTest, AllBFloat16) {
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16addl(2L, 3L));
EXPECT_FP_EQ(bfloat16(10.0),
LIBC_NAMESPACE::shared::bf16fmaf(2.0f, 3.0f, 4.0f));
- EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0)));
EXPECT_FP_EQ(bfloat16(0.0),
LIBC_NAMESPACE::shared::fdimbf16(bfloat16(0.0), bfloat16(0.0)));
>From 54e4eeb0fb7e5b3dc29b62a496e6a75e5b96ad99 Mon Sep 17 00:00:00 2001
From: bassiounix <muhammad.m.bassiouni at gmail.com>
Date: Fri, 6 Mar 2026 07:15:14 +0200
Subject: [PATCH 2/2] reapply static
---
libc/src/__support/CPP/bit.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h
index aa340b380fd32..0ba8b9219a317 100644
--- a/libc/src/__support/CPP/bit.h
+++ b/libc/src/__support/CPP/bit.h
@@ -40,7 +40,7 @@ LIBC_INLINE LIBC_CONSTEXPR void inline_copy(const char *from, char *to) {
// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
template <typename To, typename From>
-LIBC_INLINE constexpr cpp::enable_if_t<
+LIBC_INLINE static constexpr cpp::enable_if_t<
(sizeof(To) == sizeof(From)) &&
cpp::is_trivially_constructible<To>::value &&
cpp::is_trivially_copyable<To>::value &&
More information about the llvm-branch-commits
mailing list