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 [[nodiscard]] T bit_ceil(T Value) { return T(1) << llvm::bit_width(Value - 1u); } -// Forward-declare rotr so that rotl can use it. -template >> -[[nodiscard]] constexpr T rotr(T V, int R); - template >> [[nodiscard]] constexpr T rotl(T V, int R) { - unsigned N = std::numeric_limits::digits; + constexpr unsigned N = std::numeric_limits::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 [[nodiscard]] constexpr T rotr(T V, int R) { - unsigned N = std::numeric_limits::digits; +template >> +[[nodiscard]] constexpr T rotr(T V, int R) { + constexpr unsigned N = std::numeric_limits::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)); }