Index: llvm/include/llvm/ADT/BitVector.h =================================================================== --- llvm/include/llvm/ADT/BitVector.h +++ 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. Index: llvm/include/llvm/ADT/SmallBitVector.h =================================================================== --- llvm/include/llvm/ADT/SmallBitVector.h +++ llvm/include/llvm/ADT/SmallBitVector.h @@ -668,8 +668,18 @@ } bool isInvalid() const { return X == (uintptr_t)-1; } - ArrayRef getData() const { - return isSmall() ? makeArrayRef(X) : getPointer()->getData(); + unsigned getDenseMapHashValue() const { + using HashType = std::pair>; + HashType H; + H.first = size(); + uintptr_t Word; + if (isSmall()) { + Word = getSmallBits(); + H.second = ArrayRef(Word); + } else { + H.second = getPointer()->getData(); + } + return DenseMapInfo::getHashValue(H); } private: @@ -717,8 +727,7 @@ return V; } static unsigned getHashValue(const SmallBitVector &V) { - return DenseMapInfo>>::getHashValue( - std::make_pair(V.size(), V.getData())); + return V.getDenseMapHashValue(); } static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) { if (LHS.isInvalid() || RHS.isInvalid()) Index: llvm/unittests/ADT/BitVectorTest.cpp =================================================================== --- llvm/unittests/ADT/BitVectorTest.cpp +++ llvm/unittests/ADT/BitVectorTest.cpp @@ -1229,4 +1229,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