[libcxx-commits] [libcxx] [libc++][math] Add constexpr for std::abs() (PR #146633)
Arjun Patel via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jul 2 12:21:16 PDT 2025
https://github.com/arjunUpatel updated https://github.com/llvm/llvm-project/pull/146633
>From 5c135a1b2f5ca89bfb6d1c43ef17cd95c892ea82 Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:14:13 -0400
Subject: [PATCH 1/5] Update abs test
---
libcxx/test/std/numerics/c.math/abs.pass.cpp | 30 +++++++++++++-------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/libcxx/test/std/numerics/c.math/abs.pass.cpp b/libcxx/test/std/numerics/c.math/abs.pass.cpp
index 51aee6e986836..908620b2a3290 100644
--- a/libcxx/test/std/numerics/c.math/abs.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/abs.pass.cpp
@@ -20,21 +20,29 @@ struct correct_size_int {
};
template <class Source, class Result>
-void test_abs() {
- Source neg_val = -5;
- Source pos_val = 5;
- Result res = 5;
+TEST_CONSTEXPR_CXX23 void test_abs() {
+ TEST_CONSTEXPR_CXX23 Source neg_val = -5;
+ TEST_CONSTEXPR_CXX23 Source pos_val = 5;
+ TEST_CONSTEXPR_CXX23 Result res = 5;
ASSERT_SAME_TYPE(decltype(std::abs(neg_val)), Result);
-
- assert(std::abs(neg_val) == res);
- assert(std::abs(pos_val) == res);
+ #if TEST_STD_VER >= 23
+ static_assert(std::abs(neg_val) == res);
+ static_assert(std::abs(pos_val) == res);
+ #else
+ assert(std::abs(neg_val) == res);
+ assert(std::abs(pos_val) == res);
+ #endif
}
-void test_big() {
- long long int big_value = std::numeric_limits<long long int>::max(); // a value too big for ints to store
- long long int negative_big_value = -big_value;
- assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+TEST_CONSTEXPR_CXX23 void test_big() {
+ TEST_CONSTEXPR_CXX23 long long int big_value = std::numeric_limits<long long int>::max(); // a value too big for ints to store
+ TEST_CONSTEXPR_CXX23 long long int negative_big_value = -big_value;
+ #if TEST_STD_VER >= 23
+ static_assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+ #else
+ assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+ #endif
}
// The following is helpful to keep in mind:
>From 32d133a20a41cfc936e8f8dae9f05b951692c3c9 Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:27:59 -0400
Subject: [PATCH 2/5] Make abs traits constexpr
---
libcxx/include/__math/abs.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/libcxx/include/__math/abs.h b/libcxx/include/__math/abs.h
index b780159f11ebf..a1d5854ac8878 100644
--- a/libcxx/include/__math/abs.h
+++ b/libcxx/include/__math/abs.h
@@ -41,25 +41,25 @@ template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
// abs
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
return __builtin_fabsl(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
return __builtin_abs(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
return __builtin_labs(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
return __builtin_llabs(__x);
}
>From c8434670860850b14a47b64e13b6680b85554b7e Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:29:49 -0400
Subject: [PATCH 3/5] Update clang cpp23 constexpr tests
---
.../numerics/c.math/constexpr-cxx23-clang.pass.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
index 3f17f21e8c108..64164240c8564 100644
--- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
+++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
@@ -40,12 +40,12 @@ int main(int, char**) {
double DummyDouble;
long double DummyLongDouble;
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1) == 1);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
ASSERT_NOT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
ASSERT_NOT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
>From 4f49c871162f8e95d0867dbcbccd5b870f6a657a Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 14:56:07 -0400
Subject: [PATCH 4/5] Update gcc cpp23 constexpr tests
---
.../numerics/c.math/constexpr-cxx23-gcc.pass.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-gcc.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
index d8779706bcee2..a4dcd3eb0fac7 100644
--- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
+++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
@@ -38,11 +38,11 @@ int main(int, char**) {
long double DummyLongDouble;
ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
ASSERT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
ASSERT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
>From c07b0d8f7c8abe9f00f1e423f995b263c8e5f551 Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 15:20:55 -0400
Subject: [PATCH 5/5] Check constexpr builtins for clang
---
.../c.math/constexpr-cxx23-clang.pass.cpp | 37 ++++++++++++++++---
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
index 64164240c8564..675270264ce7c 100644
--- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
+++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
@@ -40,12 +40,37 @@ int main(int, char**) {
double DummyDouble;
long double DummyLongDouble;
- ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
- ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
- ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
- ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
- ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
- ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ // TODO(LLVM 22): Remove `__has_constexpr_builtin` conditional once support for Clang 19 is dropped.
+ #if __has_constexpr_builtin(__builtin_abs)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ #endif
+ #if __has_constexpr_builtin(__builtin_labs)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ #endif
+ #if __has_constexpr_builtin(__builtin_llabs)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ #endif
+ #if __has_constexpr_builtin(__builtin_fabsf)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ #endif
+ #if __has_constexpr_builtin(__builtin_fabs)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ #endif
+ #if __has_constexpr_builtin(__builtin_fabsl)
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ #else
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ #endif
ASSERT_NOT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
ASSERT_NOT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
More information about the libcxx-commits
mailing list