diff --git a/llvm/include/llvm/ADT/BitVector.h b/llvm/include/llvm/ADT/BitVector.h --- a/llvm/include/llvm/ADT/BitVector.h +++ b/llvm/include/llvm/ADT/BitVector.h @@ -759,7 +759,9 @@ } bool isInvalid() const { return Size == (unsigned)-1; } - ArrayRef getData() const { return Bits; } + ArrayRef getData() const { + return Bits.take_front(NumBitWords(size())); + } //===--------------------------------------------------------------------===// // Portable bit mask operations. diff --git a/llvm/include/llvm/ADT/SmallBitVector.h b/llvm/include/llvm/ADT/SmallBitVector.h --- a/llvm/include/llvm/ADT/SmallBitVector.h +++ b/llvm/include/llvm/ADT/SmallBitVector.h @@ -668,8 +668,11 @@ } bool isInvalid() const { return X == (uintptr_t)-1; } - ArrayRef getData() const { - return isSmall() ? makeArrayRef(X) : getPointer()->getData(); + ArrayRef getData(uintptr_t &Store) const { + if (!isSmall()) + return getPointer()->getData(); + Store = getSmallBits(); + return makeArrayRef(Store); } private: @@ -717,8 +720,9 @@ return V; } static unsigned getHashValue(const SmallBitVector &V) { + uintptr_t Store; return DenseMapInfo>>::getHashValue( - std::make_pair(V.size(), V.getData())); + std::make_pair(V.size(), V.getData(Store))); } static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) { if (LHS.isInvalid() || RHS.isInvalid()) diff --git a/llvm/unittests/ADT/BitVectorTest.cpp b/llvm/unittests/ADT/BitVectorTest.cpp --- a/llvm/unittests/ADT/BitVectorTest.cpp +++ b/llvm/unittests/ADT/BitVectorTest.cpp @@ -1204,4 +1204,34 @@ EXPECT_EQ(true, Set.erase(A)); EXPECT_EQ(0U, Set.size()); } + +/// Test that capacity doesn't affect hashing. +TYPED_TEST(BitVectorTest, DenseMapHashing) { + using DMI = DenseMapInfo; + { + TypeParam A; + A.resize(200); + A.set(100); + + TypeParam B; + B.resize(200); + B.set(100); + B.reserve(1000); + + EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B)); + } + { + TypeParam A; + A.resize(20); + A.set(10); + + TypeParam B; + B.resize(20); + B.set(10); + B.reserve(1000); + + EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B)); + } +} + } // namespace