From a51941f3140cf0ed5c79bf828ff3e418fc5df71d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 8 May 2017 04:55:09 +0000 Subject: [PATCH] [APInt] Add support for multiplying by a uint64_t. This makes multiply similar to add, sub, xor, and, and or. llvm-svn: 302402 --- llvm/include/llvm/ADT/APInt.h | 11 +++++++++++ llvm/lib/Support/APInt.cpp | 10 ++++++++++ llvm/unittests/ADT/APIntTest.cpp | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 63c92c1..c3822e3 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -842,6 +842,7 @@ public: /// /// \returns *this APInt &operator*=(const APInt &RHS); + APInt &operator*=(uint64_t RHS); /// \brief Addition assignment operator. /// @@ -2043,6 +2044,16 @@ inline APInt operator-(uint64_t LHS, APInt b) { return b; } +inline APInt operator*(APInt a, uint64_t RHS) { + a *= RHS; + return a; +} + +inline APInt operator*(uint64_t LHS, APInt b) { + b *= LHS; + return b; +} + namespace APIntOps { diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index ee5c9f9..e2cfb90 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -256,6 +256,16 @@ APInt& APInt::operator*=(const APInt& RHS) { return *this; } +APInt& APInt::operator*=(uint64_t RHS) { + if (isSingleWord()) { + U.VAL *= RHS; + } else { + unsigned NumWords = getNumWords(); + tcMultiplyPart(U.pVal, U.pVal, RHS, 0, NumWords, NumWords, false); + } + return clearUnusedBits(); +} + bool APInt::EqualSlowCase(const APInt& RHS) const { return std::equal(U.pVal, U.pVal + getNumWords(), RHS.U.pVal); } diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index bb6cf35..5594955 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -2142,4 +2142,23 @@ TEST(APIntTest, sext) { EXPECT_EQ(63U, i32_neg1.countPopulation()); } +TEST(APIntTest, multiply) { + APInt i64(64, 1234); + + EXPECT_EQ(7006652, i64 * 5678); + EXPECT_EQ(7006652, 5678 * i64); + + APInt i128 = APInt::getOneBitSet(128, 64); + APInt i128_1234(128, 1234); + i128_1234 <<= 64; + EXPECT_EQ(i128_1234, i128 * 1234); + EXPECT_EQ(i128_1234, 1234 * i128); + + APInt i96 = APInt::getOneBitSet(96, 64); + i96 *= ~0ULL; + EXPECT_EQ(32U, i96.countLeadingOnes()); + EXPECT_EQ(32U, i96.countPopulation()); + EXPECT_EQ(64U, i96.countTrailingZeros()); +} + } // end anonymous namespace -- 2.7.4