From 6606815993b6bad49025aa1d0517755a4d8c8748 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Tue, 30 Jul 2019 07:09:41 +0000 Subject: [PATCH] [APInt] Introduce clearLowBits() Summary: Equivalent to `x & -2^K`. Reviewers: RKSimon, craig.topper Reviewed By: RKSimon, craig.topper Subscribers: dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65369 llvm-svn: 367287 --- llvm/include/llvm/ADT/APInt.h | 7 +++++ llvm/unittests/ADT/APIntTest.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 2381b75..987ca63 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -1467,6 +1467,13 @@ public: U.pVal[whichWord(BitPosition)] &= Mask; } + /// Set bottom loBits bits to 0. + void clearLowBits(unsigned loBits) { + assert(loBits <= BitWidth && "More bits than bitwidth"); + APInt Keep = getHighBitsSet(BitWidth, BitWidth - loBits); + *this &= Keep; + } + /// Set the sign bit to 0. void clearSignBit() { clearBit(BitWidth - 1); diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 4ab79e4..4c576ea 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -2117,6 +2117,71 @@ TEST(APIntTest, getHiBits) { EXPECT_EQ(0xc, i128.getHiBits(4)); } +TEST(APIntTest, clearLowBits) { + APInt i64hi32 = APInt::getAllOnesValue(64); + i64hi32.clearLowBits(32); + EXPECT_EQ(32u, i64hi32.countLeadingOnes()); + EXPECT_EQ(0u, i64hi32.countLeadingZeros()); + EXPECT_EQ(64u, i64hi32.getActiveBits()); + EXPECT_EQ(32u, i64hi32.countTrailingZeros()); + EXPECT_EQ(0u, i64hi32.countTrailingOnes()); + EXPECT_EQ(32u, i64hi32.countPopulation()); + + APInt i128hi64 = APInt::getAllOnesValue(128); + i128hi64.clearLowBits(64); + EXPECT_EQ(64u, i128hi64.countLeadingOnes()); + EXPECT_EQ(0u, i128hi64.countLeadingZeros()); + EXPECT_EQ(128u, i128hi64.getActiveBits()); + EXPECT_EQ(64u, i128hi64.countTrailingZeros()); + EXPECT_EQ(0u, i128hi64.countTrailingOnes()); + EXPECT_EQ(64u, i128hi64.countPopulation()); + + APInt i128hi24 = APInt::getAllOnesValue(128); + i128hi24.clearLowBits(104); + EXPECT_EQ(24u, i128hi24.countLeadingOnes()); + EXPECT_EQ(0u, i128hi24.countLeadingZeros()); + EXPECT_EQ(128u, i128hi24.getActiveBits()); + EXPECT_EQ(104u, i128hi24.countTrailingZeros()); + EXPECT_EQ(0u, i128hi24.countTrailingOnes()); + EXPECT_EQ(24u, i128hi24.countPopulation()); + + APInt i128hi104 = APInt::getAllOnesValue(128); + i128hi104.clearLowBits(24); + EXPECT_EQ(104u, i128hi104.countLeadingOnes()); + EXPECT_EQ(0u, i128hi104.countLeadingZeros()); + EXPECT_EQ(128u, i128hi104.getActiveBits()); + EXPECT_EQ(24u, i128hi104.countTrailingZeros()); + EXPECT_EQ(0u, i128hi104.countTrailingOnes()); + EXPECT_EQ(104u, i128hi104.countPopulation()); + + APInt i128hi0 = APInt::getAllOnesValue(128); + i128hi0.clearLowBits(128); + EXPECT_EQ(0u, i128hi0.countLeadingOnes()); + EXPECT_EQ(128u, i128hi0.countLeadingZeros()); + EXPECT_EQ(0u, i128hi0.getActiveBits()); + EXPECT_EQ(128u, i128hi0.countTrailingZeros()); + EXPECT_EQ(0u, i128hi0.countTrailingOnes()); + EXPECT_EQ(0u, i128hi0.countPopulation()); + + APInt i80hi1 = APInt::getAllOnesValue(80); + i80hi1.clearLowBits(79); + EXPECT_EQ(1u, i80hi1.countLeadingOnes()); + EXPECT_EQ(0u, i80hi1.countLeadingZeros()); + EXPECT_EQ(80u, i80hi1.getActiveBits()); + EXPECT_EQ(79u, i80hi1.countTrailingZeros()); + EXPECT_EQ(0u, i80hi1.countTrailingOnes()); + EXPECT_EQ(1u, i80hi1.countPopulation()); + + APInt i32hi16 = APInt::getAllOnesValue(32); + i32hi16.clearLowBits(16); + EXPECT_EQ(16u, i32hi16.countLeadingOnes()); + EXPECT_EQ(0u, i32hi16.countLeadingZeros()); + EXPECT_EQ(32u, i32hi16.getActiveBits()); + EXPECT_EQ(16u, i32hi16.countTrailingZeros()); + EXPECT_EQ(0u, i32hi16.countTrailingOnes()); + EXPECT_EQ(16u, i32hi16.countPopulation()); +} + TEST(APIntTest, GCD) { using APIntOps::GreatestCommonDivisor; -- 2.7.4