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 @@ -287,11 +287,11 @@ /// Returns -1 if the next unset bit is not found. int find_next_unset(unsigned Prev) const { if (isSmall()) { - ++Prev; uintptr_t Bits = getSmallBits(); // Mask in previous bits. - uintptr_t Mask = (uintptr_t(1) << Prev) - 1; - Bits |= Mask; + Bits |= (uintptr_t(1) << (Prev + 1)) - 1; + // Mask in unused bits. + Bits |= ~uintptr_t(0) << getSmallSize(); if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize()) return -1; 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 @@ -297,6 +297,18 @@ EXPECT_EQ(-1, A.find_last_unset()); A.resize(20); + ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); + EXPECT_EQ(-1, A.find_first()); + EXPECT_EQ(-1, A.find_last()); + EXPECT_EQ(-1, A.find_next(5)); + EXPECT_EQ(-1, A.find_next(19)); + EXPECT_EQ(-1, A.find_prev(5)); + EXPECT_EQ(-1, A.find_prev(20)); + EXPECT_EQ(0, A.find_first_unset()); + EXPECT_EQ(19, A.find_last_unset()); + EXPECT_EQ(6, A.find_next_unset(5)); + EXPECT_EQ(-1, A.find_next_unset(19)); + A.set(3); A.set(4); A.set(16); @@ -319,6 +331,19 @@ EXPECT_EQ(5, A.find_next_unset(4)); EXPECT_EQ(13, A.find_next_unset(12)); EXPECT_EQ(17, A.find_next_unset(15)); + + A.set(); + ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); + EXPECT_EQ(0, A.find_first()); + EXPECT_EQ(19, A.find_last()); + EXPECT_EQ(6, A.find_next(5)); + EXPECT_EQ(-1, A.find_next(19)); + EXPECT_EQ(4, A.find_prev(5)); + EXPECT_EQ(19, A.find_prev(20)); + EXPECT_EQ(-1, A.find_first_unset()); + EXPECT_EQ(-1, A.find_last_unset()); + EXPECT_EQ(-1, A.find_next_unset(5)); + EXPECT_EQ(-1, A.find_next_unset(19)); } TEST(BitVectorTest, FindInRangeMultiWord) {