Skip to content

Commit

Permalink
[ADT] Introduce APInt::clearHighBits (llvm#91938)
Browse files Browse the repository at this point in the history
This patch addresses
llvm#90034 (comment).
  • Loading branch information
dtcxzyw authored May 13, 2024
1 parent 4b44502 commit 99934da
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/ADT/APInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,13 @@ class [[nodiscard]] APInt {
*this &= Keep;
}

/// Set top hiBits bits to 0.
void clearHighBits(unsigned hiBits) {
assert(hiBits <= BitWidth && "More bits than bitwidth");
APInt Keep = getLowBitsSet(BitWidth, BitWidth - hiBits);
*this &= Keep;
}

/// Set the sign bit to 0.
void clearSignBit() { clearBit(BitWidth - 1); }

Expand Down
65 changes: 65 additions & 0 deletions llvm/unittests/ADT/APIntTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2534,6 +2534,71 @@ TEST(APIntTest, clearLowBits) {
EXPECT_EQ(16u, i32hi16.popcount());
}

TEST(APIntTest, clearHighBits) {
APInt i64hi32 = APInt::getAllOnes(64);
i64hi32.clearHighBits(32);
EXPECT_EQ(32u, i64hi32.countr_one());
EXPECT_EQ(0u, i64hi32.countr_zero());
EXPECT_EQ(32u, i64hi32.getActiveBits());
EXPECT_EQ(32u, i64hi32.countl_zero());
EXPECT_EQ(0u, i64hi32.countl_one());
EXPECT_EQ(32u, i64hi32.popcount());

APInt i128hi64 = APInt::getAllOnes(128);
i128hi64.clearHighBits(64);
EXPECT_EQ(64u, i128hi64.countr_one());
EXPECT_EQ(0u, i128hi64.countr_zero());
EXPECT_EQ(64u, i128hi64.getActiveBits());
EXPECT_EQ(64u, i128hi64.countl_zero());
EXPECT_EQ(0u, i128hi64.countl_one());
EXPECT_EQ(64u, i128hi64.popcount());

APInt i128hi24 = APInt::getAllOnes(128);
i128hi24.clearHighBits(104);
EXPECT_EQ(24u, i128hi24.countr_one());
EXPECT_EQ(0u, i128hi24.countr_zero());
EXPECT_EQ(24u, i128hi24.getActiveBits());
EXPECT_EQ(104u, i128hi24.countl_zero());
EXPECT_EQ(0u, i128hi24.countl_one());
EXPECT_EQ(24u, i128hi24.popcount());

APInt i128hi104 = APInt::getAllOnes(128);
i128hi104.clearHighBits(24);
EXPECT_EQ(104u, i128hi104.countr_one());
EXPECT_EQ(0u, i128hi104.countr_zero());
EXPECT_EQ(104u, i128hi104.getActiveBits());
EXPECT_EQ(24u, i128hi104.countl_zero());
EXPECT_EQ(0u, i128hi104.countl_one());
EXPECT_EQ(104u, i128hi104.popcount());

APInt i128hi0 = APInt::getAllOnes(128);
i128hi0.clearHighBits(128);
EXPECT_EQ(0u, i128hi0.countr_one());
EXPECT_EQ(128u, i128hi0.countr_zero());
EXPECT_EQ(0u, i128hi0.getActiveBits());
EXPECT_EQ(128u, i128hi0.countl_zero());
EXPECT_EQ(0u, i128hi0.countl_one());
EXPECT_EQ(0u, i128hi0.popcount());

APInt i80hi1 = APInt::getAllOnes(80);
i80hi1.clearHighBits(79);
EXPECT_EQ(1u, i80hi1.countr_one());
EXPECT_EQ(0u, i80hi1.countr_zero());
EXPECT_EQ(1u, i80hi1.getActiveBits());
EXPECT_EQ(79u, i80hi1.countl_zero());
EXPECT_EQ(0u, i80hi1.countl_one());
EXPECT_EQ(1u, i80hi1.popcount());

APInt i32hi16 = APInt::getAllOnes(32);
i32hi16.clearHighBits(16);
EXPECT_EQ(16u, i32hi16.countr_one());
EXPECT_EQ(0u, i32hi16.countr_zero());
EXPECT_EQ(16u, i32hi16.getActiveBits());
EXPECT_EQ(16u, i32hi16.countl_zero());
EXPECT_EQ(0u, i32hi16.countl_one());
EXPECT_EQ(16u, i32hi16.popcount());
}

TEST(APIntTest, abds) {
using APIntOps::abds;

Expand Down

0 comments on commit 99934da

Please sign in to comment.