Skip to content

Conversation

@kazutakahirata
Copy link
Contributor

This patch simplifies rotl and rotr by ANDing the rotate amount with
N - 1. This way, we can remove the mutual dependencies and the
forward declaration of rotr.

This patch simplifies rotl and rotr by ANDing the rotate amount with
N - 1.  This way, we can remove the mutual dependencies and the
forward declaration of rotr.
@llvmbot
Copy link
Member

llvmbot commented Oct 18, 2025

@llvm/pr-subscribers-llvm-adt

Author: Kazu Hirata (kazutakahirata)

Changes

This patch simplifies rotl and rotr by ANDing the rotate amount with
N - 1. This way, we can remove the mutual dependencies and the
forward declaration of rotr.


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

1 Files Affected:

  • (modified) llvm/include/llvm/ADT/bit.h (+12-17)
diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
index 66c4f94813241..8c68d0a90c753 100644
--- a/llvm/include/llvm/ADT/bit.h
+++ b/llvm/include/llvm/ADT/bit.h
@@ -336,33 +336,28 @@ template <typename T> [[nodiscard]] T bit_ceil(T Value) {
   return T(1) << llvm::bit_width<T>(Value - 1u);
 }
 
-// Forward-declare rotr so that rotl can use it.
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-[[nodiscard]] constexpr T rotr(T V, int R);
-
 template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
 [[nodiscard]] constexpr T rotl(T V, int R) {
-  unsigned N = std::numeric_limits<T>::digits;
+  constexpr unsigned N = std::numeric_limits<T>::digits;
 
-  R = R % N;
-  if (!R)
-    return V;
+  static_assert(has_single_bit(N), "& (N - 1) is only valid for powers of two");
+  R = R & (N - 1);
 
-  if (R < 0)
-    return llvm::rotr(V, -R);
+  if (R == 0)
+    return V;
 
   return (V << R) | (V >> (N - R));
 }
 
-template <typename T, typename> [[nodiscard]] constexpr T rotr(T V, int R) {
-  unsigned N = std::numeric_limits<T>::digits;
+template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
+[[nodiscard]] constexpr T rotr(T V, int R) {
+  constexpr unsigned N = std::numeric_limits<T>::digits;
 
-  R = R % N;
-  if (!R)
-    return V;
+  static_assert(has_single_bit(N), "& (N - 1) is only valid for powers of two");
+  R = R & (N - 1);
 
-  if (R < 0)
-    return llvm::rotl(V, -R);
+  if (R == 0)
+    return V;
 
   return (V >> R) | (V << (N - R));
 }

@kazutakahirata kazutakahirata merged commit e3609ae into llvm:main Oct 18, 2025
12 checks passed
@kazutakahirata kazutakahirata deleted the cleanup_20251017_ADT_bit_rotl_rotr branch October 18, 2025 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants