Skip to content

Conversation

philnik777
Copy link
Contributor

No description provided.

@philnik777 philnik777 marked this pull request as ready for review September 24, 2025 08:34
@philnik777 philnik777 requested a review from a team as a code owner September 24, 2025 08:34
@philnik777 philnik777 merged commit 330522e into llvm:main Sep 24, 2025
80 checks passed
@philnik777 philnik777 deleted the simplify_bit_functions branch September 24, 2025 08:35
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 24, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/160267.diff

5 Files Affected:

  • (modified) libcxx/include/__bit/countl.h (+1-1)
  • (modified) libcxx/include/__bit/countr.h (+1-1)
  • (modified) libcxx/include/__bit/has_single_bit.h (+1-1)
  • (modified) libcxx/include/__bit/rotate.h (+15-26)
  • (modified) libcxx/test/libcxx/numerics/bit.ops.pass.cpp (-3)
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants