[libcxx-commits] [libcxx] [libc++] Simplify some of the <bit> functions (PR #160267)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 23 03:04:12 PDT 2025


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/160267

None

>From a8d22cb040cb64d831c5f5bd042f170424339a62 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 23 Sep 2025 12:03:52 +0200
Subject: [PATCH] [libc++] Simplify some of the <bit> functions

---
 libcxx/include/__bit/countl.h                |  2 +-
 libcxx/include/__bit/countr.h                |  2 +-
 libcxx/include/__bit/has_single_bit.h        |  2 +-
 libcxx/include/__bit/rotate.h                | 41 +++++++-------------
 libcxx/test/libcxx/numerics/bit.ops.pass.cpp |  3 --
 5 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h
index 075914020879a..29b01277fb0eb 100644
--- a/libcxx/include/__bit/countl.h
+++ b/libcxx/include/__bit/countl.h
@@ -37,7 +37,7 @@ template <__unsigned_integer _Tp>
 
 template <__unsigned_integer _Tp>
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
-  return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
+  return std::countl_zero(static_cast<_Tp>(~__t));
 }
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h
index f6c98695d3d06..4de887ad4f67c 100644
--- a/libcxx/include/__bit/countr.h
+++ b/libcxx/include/__bit/countr.h
@@ -37,7 +37,7 @@ template <__unsigned_integer _Tp>
 
 template <__unsigned_integer _Tp>
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
-  return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
+  return std::countr_zero(static_cast<_Tp>(~__t));
 }
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h
index b43e69323e77b..d10ab7d6c1791 100644
--- a/libcxx/include/__bit/has_single_bit.h
+++ b/libcxx/include/__bit/has_single_bit.h
@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <__unsigned_integer _Tp>
 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
-  return __t != 0 && (((__t & (__t - 1)) == 0));
+  return __t != 0 && ((__t & (__t - 1)) == 0);
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__bit/rotate.h b/libcxx/include/__bit/rotate.h
index c6f34bdaf6e63..fde9058887779 100644
--- a/libcxx/include/__bit/rotate.h
+++ b/libcxx/include/__bit/rotate.h
@@ -22,46 +22,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // Writing two full functions for rotl and rotr makes it easier for the compiler
 // to optimize the code. On x86 this function becomes the ROL instruction and
 // the rotr function becomes the ROR instruction.
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT {
-  static_assert(__is_unsigned_integer_v<_Tp>, "__rotl requires an unsigned integer type");
+
+#if _LIBCPP_STD_VER >= 20
+
+template <__unsigned_integer _Tp>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
   const int __n = numeric_limits<_Tp>::digits;
-  int __r       = __s % __n;
+  int __r       = __cnt % __n;
 
   if (__r == 0)
-    return __x;
+    return __t;
 
   if (__r > 0)
-    return (__x << __r) | (__x >> (__n - __r));
+    return (__t << __r) | (__t >> (__n - __r));
 
-  return (__x >> -__r) | (__x << (__n + __r));
+  return (__t >> -__r) | (__t << (__n + __r));
 }
 
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT {
-  static_assert(__is_unsigned_integer_v<_Tp>, "__rotr requires an unsigned integer type");
+template <__unsigned_integer _Tp>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
   const int __n = numeric_limits<_Tp>::digits;
-  int __r       = __s % __n;
+  int __r       = __cnt % __n;
 
   if (__r == 0)
-    return __x;
+    return __t;
 
   if (__r > 0)
-    return (__x >> __r) | (__x << (__n - __r));
-
-  return (__x << -__r) | (__x >> (__n + __r));
-}
+    return (__t >> __r) | (__t << (__n - __r));
 
-#if _LIBCPP_STD_VER >= 20
-
-template <__unsigned_integer _Tp>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
-  return std::__rotl(__t, __cnt);
-}
-
-template <__unsigned_integer _Tp>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
-  return std::__rotr(__t, __cnt);
+  return (__t << -__r) | (__t >> (__n + __r));
 }
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/test/libcxx/numerics/bit.ops.pass.cpp b/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
index 7f502d6e01d1e..061f7030eca0b 100644
--- a/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
+++ b/libcxx/test/libcxx/numerics/bit.ops.pass.cpp
@@ -11,7 +11,6 @@
 
 #include <__bit/bit_log2.h>
 #include <__bit/countl.h>
-#include <__bit/rotate.h>
 #include <cassert>
 
 #include "test_macros.h"
@@ -19,10 +18,8 @@
 TEST_CONSTEXPR_CXX14 bool test() {
   const unsigned v = 0x12345678;
 
-  ASSERT_SAME_TYPE(unsigned, decltype(std::__rotr(v, 3)));
   ASSERT_SAME_TYPE(int, decltype(std::__countl_zero(v)));
 
-  assert(std::__rotr(v, 3) == 0x02468acfU);
   assert(std::__countl_zero(v) == 3);
 
 #if TEST_STD_VER > 17



More information about the libcxx-commits mailing list