[llvm] 336a4e0 - [ADT] Add llvm::has_single_bit helper similar to the c++20 std::has_single_bit implementation

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 23 11:51:31 PDT 2022


Author: Simon Pilgrim
Date: 2022-08-23T19:51:05+01:00
New Revision: 336a4e03a439b312092a03e0b005f9a0b7051518

URL: https://github.com/llvm/llvm-project/commit/336a4e03a439b312092a03e0b005f9a0b7051518
DIFF: https://github.com/llvm/llvm-project/commit/336a4e03a439b312092a03e0b005f9a0b7051518.diff

LOG: [ADT] Add llvm::has_single_bit helper similar to the c++20 std::has_single_bit implementation

Converted the llvm::isPowerOf2_32/64 helpers into wrappers

Added: 
    

Modified: 
    llvm/include/llvm/ADT/bit.h
    llvm/include/llvm/Support/MathExtras.h
    llvm/unittests/ADT/BitTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
index f57bc6f44048..2fb10ef672a5 100644
--- a/llvm/include/llvm/ADT/bit.h
+++ b/llvm/include/llvm/ADT/bit.h
@@ -34,6 +34,11 @@ inline To bit_cast(const From &from) noexcept {
   return to;
 }
 
+template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
+constexpr inline bool has_single_bit(T Value) noexcept {
+  return (Value != 0) && ((Value & (Value - 1)) == 0);
+}
+
 namespace detail {
 template <typename T, std::size_t SizeOfT> struct PopulationCounter {
   static int count(T Value) {

diff  --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 2e5d77e3290f..ca3e7b976663 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -486,12 +486,12 @@ constexpr inline bool isShiftedMask_64(uint64_t Value) {
 /// Return true if the argument is a power of two > 0.
 /// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
 constexpr inline bool isPowerOf2_32(uint32_t Value) {
-  return Value && !(Value & (Value - 1));
+  return llvm::has_single_bit(Value);
 }
 
 /// Return true if the argument is a power of two > 0 (64 bit edition.)
 constexpr inline bool isPowerOf2_64(uint64_t Value) {
-  return Value && !(Value & (Value - 1));
+  return llvm::has_single_bit(Value);
 }
 
 /// Count the number of ones from the most significant bit to the first

diff  --git a/llvm/unittests/ADT/BitTest.cpp b/llvm/unittests/ADT/BitTest.cpp
index 59af29d872a2..bd3e3439f1e6 100644
--- a/llvm/unittests/ADT/BitTest.cpp
+++ b/llvm/unittests/ADT/BitTest.cpp
@@ -31,6 +31,23 @@ TEST(BitTest, BitCast) {
                    llvm::bit_cast<double>(llvm::bit_cast<uint64_t>(kValueF64)));
 }
 
+TEST(BitTest, HasSingleBit) {
+  EXPECT_FALSE(llvm::has_single_bit(0U));
+  EXPECT_FALSE(llvm::has_single_bit(0ULL));
+
+  EXPECT_FALSE(llvm::has_single_bit(~0U));
+  EXPECT_FALSE(llvm::has_single_bit(~0ULL));
+
+  EXPECT_TRUE(llvm::has_single_bit(1U));
+  EXPECT_TRUE(llvm::has_single_bit(1ULL));
+
+  static const int8_t kValueS8 = -128;
+  EXPECT_TRUE(llvm::has_single_bit(static_cast<uint8_t>(kValueS8)));
+
+  static const int16_t kValueS16 = -32768;
+  EXPECT_TRUE(llvm::has_single_bit(static_cast<uint16_t>(kValueS16)));
+}
+
 TEST(BitTest, PopCount) {
   EXPECT_EQ(0, llvm::popcount(0U));
   EXPECT_EQ(0, llvm::popcount(0ULL));


        


More information about the llvm-commits mailing list