[llvm] Refactor LaneBitmask to be a Bitset (PR #191757)

Robert Imschweiler via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 13 12:50:59 PDT 2026


================
@@ -29,72 +29,193 @@
 #ifndef LLVM_MC_LANEBITMASK_H
 #define LLVM_MC_LANEBITMASK_H
 
-#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Bitset.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Printable.h"
 #include "llvm/Support/raw_ostream.h"
+#include <array>
+#include <cassert>
 
-namespace llvm {
+namespace llvm::detail {
+template <unsigned NumBits> struct LaneBitmaskImpl : public Bitset<NumBits> {
+  static constexpr unsigned BitWidth = NumBits;
 
-  struct LaneBitmask {
-    // When changing the underlying type, change the format string as well.
-    using Type = uint64_t;
-    enum : unsigned { BitWidth = 8*sizeof(Type) };
-    constexpr static const char *const FormatStr = "%016llX";
+  constexpr LaneBitmaskImpl() = default;
+  constexpr LaneBitmaskImpl(const LaneBitmaskImpl &) = default;
+  explicit constexpr LaneBitmaskImpl(uint64_t V)
+      : Bitset<NumBits>(std::array<uint64_t, (NumBits + 63) / 64>{V}) {}
+  explicit constexpr LaneBitmaskImpl(
+      const std::array<uint64_t, (NumBits + 63) / 64> &B)
+      : Bitset<NumBits>(B) {}
+  explicit LaneBitmaskImpl(const APInt &N)
+      : Bitset<NumBits>(convertAPIntToArray(N)) {}
+  // Delete the initializer_list constructor to avoid ambiguity with the
+  // std::array constructor.
+  LaneBitmaskImpl(std::initializer_list<unsigned>) = delete;
+  constexpr LaneBitmaskImpl &operator=(const LaneBitmaskImpl &) = default;
 
-    constexpr LaneBitmask() = default;
-    explicit constexpr LaneBitmask(Type V) : Mask(V) {}
+  /// Compare as unsigned integers (most-significant word first). This differs
+  /// from Bitset::operator< which compares bit-by-bit from LSB.
+  constexpr bool operator<(const LaneBitmaskImpl &Other) const {
+    const auto &ThisBits = this->getData();
+    const auto &OtherBits = Other.getData();
+    for (int I = ThisBits.size() - 1; I >= 0; --I) {
+      if (ThisBits[I] != OtherBits[I])
+        return ThisBits[I] < OtherBits[I];
+    }
+    return false;
+  }
 
-    constexpr bool operator== (LaneBitmask M) const { return Mask == M.Mask; }
-    constexpr bool operator!= (LaneBitmask M) const { return Mask != M.Mask; }
-    constexpr bool operator< (LaneBitmask M)  const { return Mask < M.Mask; }
-    constexpr bool none() const { return Mask == 0; }
-    constexpr bool any()  const { return Mask != 0; }
-    constexpr bool all()  const { return ~Mask == 0; }
+  constexpr LaneBitmaskImpl operator~() const {
+    return Bitset<NumBits>::operator~();
+  }
+  constexpr LaneBitmaskImpl operator|(LaneBitmaskImpl M) const {
+    return Bitset<NumBits>::operator|(M);
+  }
+  constexpr LaneBitmaskImpl operator&(LaneBitmaskImpl M) const {
+    return Bitset<NumBits>::operator&(M);
+  }
+  constexpr LaneBitmaskImpl &operator|=(LaneBitmaskImpl M) {
+    Bitset<NumBits>::operator|=(M);
+    return *this;
+  }
+  constexpr LaneBitmaskImpl &operator&=(LaneBitmaskImpl M) {
+    Bitset<NumBits>::operator&=(M);
+    return *this;
+  }
+  constexpr LaneBitmaskImpl operator^(LaneBitmaskImpl M) const {
+    return Bitset<NumBits>::operator^(M);
+  }
+  constexpr LaneBitmaskImpl &operator^=(LaneBitmaskImpl M) {
+    Bitset<NumBits>::operator^=(M);
+    return *this;
+  }
 
-    constexpr LaneBitmask operator~() const {
-      return LaneBitmask(~Mask);
-    }
-    constexpr LaneBitmask operator|(LaneBitmask M) const {
-      return LaneBitmask(Mask | M.Mask);
-    }
-    constexpr LaneBitmask operator&(LaneBitmask M) const {
-      return LaneBitmask(Mask & M.Mask);
-    }
-    LaneBitmask &operator|=(LaneBitmask M) {
-      Mask |= M.Mask;
+  constexpr size_t getNumLanes() const { return this->count(); }
+
+  unsigned getHighestLane() const {
+    assert(this->any() && "getHighestLane called on empty mask");
+    const auto &Bits = this->getData();
+    constexpr size_t WordBits = sizeof(decltype(Bits[0])) * 8;
----------------
ro-i wrote:

could use the definition in `Bitset`?

https://github.com/llvm/llvm-project/blob/db89a15f8f3a423385aae8c228487053126183d1/llvm/include/llvm/ADT/Bitset.h#L32

https://github.com/llvm/llvm-project/pull/191757


More information about the llvm-commits mailing list