[libcxx-commits] [libcxx] [libc++] std::cmp_less and other integer comparison functions could be improved (PR #151332)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 2 05:39:28 PDT 2025


https://github.com/kisuhorikka updated https://github.com/llvm/llvm-project/pull/151332

>From d98f1915ba148b36a52ad78fccd60927f7b8c1bf Mon Sep 17 00:00:00 2001
From: kisuhorikka <kisuhorikka at gmail.com>
Date: Wed, 30 Jul 2025 20:53:05 +0800
Subject: [PATCH 1/2] [libc++] std::cmp_less and other integer comparison
 functions could be improved

---
 libcxx/include/__utility/cmp.h | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h
index 14dc0c154c040..4c29f09628095 100644
--- a/libcxx/include/__utility/cmp.h
+++ b/libcxx/include/__utility/cmp.h
@@ -28,7 +28,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
 _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
-  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
+    __builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
+    return static_cast<int>(__t) == static_cast<int>(__u);
+  } else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
+    __builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
+    return static_cast<long long>(__t) == static_cast<long long>(__u);
+  } else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
     return __t == __u;
   else if constexpr (is_signed_v<_Tp>)
     return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
@@ -43,7 +49,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
 
 template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
 _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
-  if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
+    __builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
+    return static_cast<int>(__t) < static_cast<int>(__u);
+  } else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
+    __builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
+    return static_cast<long long>(__t) < static_cast<long long>(__u);
+  } else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
     return __t < __u;
   else if constexpr (is_signed_v<_Tp>)
     return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;

>From 680faaa818b85717f1d30804e44e10c69ff302e6 Mon Sep 17 00:00:00 2001
From: kisuhorikka <kisuhorikka at gmail.com>
Date: Thu, 31 Jul 2025 13:08:18 +0800
Subject: [PATCH 2/2] [libc++] std::cmp_less and other integer comparison
 functions could be improved with _LIBCPP_ASSUME

---
 libcxx/include/__utility/cmp.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/libcxx/include/__utility/cmp.h b/libcxx/include/__utility/cmp.h
index 4c29f09628095..ef9f2c34f771d 100644
--- a/libcxx/include/__utility/cmp.h
+++ b/libcxx/include/__utility/cmp.h
@@ -9,6 +9,7 @@
 #ifndef _LIBCPP___UTILITY_CMP_H
 #define _LIBCPP___UTILITY_CMP_H
 
+#include "__assert"
 #include <__config>
 #include <__type_traits/integer_traits.h>
 #include <__type_traits/is_signed.h>
@@ -28,13 +29,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
 _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
-  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
-    __builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
+  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int))
     return static_cast<int>(__t) == static_cast<int>(__u);
-  } else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
-    __builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
+  else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long))
     return static_cast<long long>(__t) == static_cast<long long>(__u);
-  } else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+  else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
     return __t == __u;
   else if constexpr (is_signed_v<_Tp>)
     return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
@@ -49,13 +48,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
 
 template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
 _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
-  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int)) {
-    __builtin_assume(__t < numeric_limits<int>::max() && __u < numeric_limits<int>::max());
+  if constexpr (sizeof(_Tp) < sizeof(int) && sizeof(_Up) < sizeof(int))
     return static_cast<int>(__t) < static_cast<int>(__u);
-  } else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long)) {
-    __builtin_assume(__t < numeric_limits<long long>::max() && __u < numeric_limits<long long>::max());
+  else if constexpr (sizeof(_Tp) < sizeof(long long) && sizeof(_Up) < sizeof(long long))
     return static_cast<long long>(__t) < static_cast<long long>(__u);
-  } else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
+  else if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
     return __t < __u;
   else if constexpr (is_signed_v<_Tp>)
     return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;



More information about the libcxx-commits mailing list