[llvm] [ADT] Simplify rotl/rotr implementations (NFC) (PR #164055)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 17 23:54:08 PDT 2025


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/164055

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.


>From 3e3f4c1f30f023358ed49864956948cd29d64b2f Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 15 Oct 2025 15:11:59 -0700
Subject: [PATCH] [ADT] Simplify rotl/rotr implementations (NFC)

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.
---
 llvm/include/llvm/ADT/bit.h | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

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));
 }



More information about the llvm-commits mailing list