Index: llvm/trunk/include/llvm/ADT/APInt.h =================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h +++ llvm/trunk/include/llvm/ADT/APInt.h @@ -196,15 +196,6 @@ /// out-of-line slow case for shl APInt shlSlowCase(unsigned shiftAmt) const; - /// out-of-line slow case for operator& - APInt AndSlowCase(const APInt &RHS) const; - - /// out-of-line slow case for operator| - APInt OrSlowCase(const APInt &RHS) const; - - /// out-of-line slow case for operator^ - APInt XorSlowCase(const APInt &RHS) const; - /// out-of-line slow case for operator= APInt &AssignSlowCase(const APInt &RHS); @@ -782,42 +773,6 @@ /// \name Binary Operators /// @{ - /// \brief Bitwise AND operator. - /// - /// Performs a bitwise AND operation on *this and RHS. - /// - /// \returns An APInt value representing the bitwise AND of *this and RHS. - APInt operator&(const APInt &RHS) const { - assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) - return APInt(getBitWidth(), VAL & RHS.VAL); - return AndSlowCase(RHS); - } - - /// \brief Bitwise OR operator. - /// - /// Performs a bitwise OR operation on *this and RHS. - /// - /// \returns An APInt value representing the bitwise OR of *this and RHS. - APInt operator|(const APInt &RHS) const { - assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) - return APInt(getBitWidth(), VAL | RHS.VAL); - return OrSlowCase(RHS); - } - - /// \brief Bitwise XOR operator. - /// - /// Performs a bitwise XOR operation on *this and RHS. - /// - /// \returns An APInt value representing the bitwise XOR of *this and RHS. - APInt operator^(const APInt &RHS) const { - assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); - if (isSingleWord()) - return APInt(BitWidth, VAL ^ RHS.VAL); - return XorSlowCase(RHS); - } - /// \brief Multiplication operator. /// /// Multiplies this APInt by RHS and returns the result. @@ -1143,7 +1098,11 @@ /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. - bool intersects(const APInt &RHS) const { return (*this & RHS) != 0; } + bool intersects(const APInt &RHS) const { + APInt temp(*this); + temp &= RHS; + return temp != 0; + } /// @} /// \name Resizing Operators @@ -1771,6 +1730,16 @@ return v; } +inline APInt operator&(APInt a, const APInt &b) { + a &= b; + return a; +} + +inline APInt operator&(const APInt &a, APInt &&b) { + b &= a; + return std::move(b); +} + inline APInt operator&(APInt a, uint64_t RHS) { a &= RHS; return a; @@ -1781,6 +1750,16 @@ return b; } +inline APInt operator|(APInt a, const APInt &b) { + a |= b; + return a; +} + +inline APInt operator|(const APInt &a, APInt &&b) { + b |= a; + return std::move(b); +} + inline APInt operator|(APInt a, uint64_t RHS) { a |= RHS; return a; @@ -1791,6 +1770,16 @@ return b; } +inline APInt operator^(APInt a, const APInt &b) { + a ^= b; + return a; +} + +inline APInt operator^(const APInt &a, APInt &&b) { + b ^= a; + return std::move(b); +} + inline APInt operator^(APInt a, uint64_t RHS) { a ^= RHS; return a; Index: llvm/trunk/lib/Support/APInt.cpp =================================================================== --- llvm/trunk/lib/Support/APInt.cpp +++ llvm/trunk/lib/Support/APInt.cpp @@ -461,31 +461,6 @@ return *this; } -APInt APInt::AndSlowCase(const APInt& RHS) const { - unsigned numWords = getNumWords(); - uint64_t* val = getMemory(numWords); - for (unsigned i = 0; i < numWords; ++i) - val[i] = pVal[i] & RHS.pVal[i]; - return APInt(val, getBitWidth()); -} - -APInt APInt::OrSlowCase(const APInt& RHS) const { - unsigned numWords = getNumWords(); - uint64_t *val = getMemory(numWords); - for (unsigned i = 0; i < numWords; ++i) - val[i] = pVal[i] | RHS.pVal[i]; - return APInt(val, getBitWidth()); -} - -APInt APInt::XorSlowCase(const APInt& RHS) const { - unsigned numWords = getNumWords(); - uint64_t *val = getMemory(numWords); - for (unsigned i = 0; i < numWords; ++i) - val[i] = pVal[i] ^ RHS.pVal[i]; - - return APInt(val, getBitWidth()); -} - APInt APInt::operator*(const APInt& RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) Index: llvm/trunk/unittests/ADT/APIntTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/APIntTest.cpp +++ llvm/trunk/unittests/ADT/APIntTest.cpp @@ -761,6 +761,126 @@ } } +TEST(APIntTest, rvalue_bitwise) { + // Test all combinations of lvalue/rvalue lhs/rhs of and/or/xor + + // Lamdba to return an APInt by value, but also provide the raw value of the + // allocated data. + auto getRValue = [](const char *HexString, uint64_t const *&RawData) { + APInt V(129, HexString, 16); + RawData = V.getRawData(); + return V; + }; + + APInt Ten(129, "A", 16); + APInt Twelve(129, "C", 16); + + const uint64_t *RawDataL = nullptr; + const uint64_t *RawDataR = nullptr; + + { + // 12 & 10 = 8 + APInt AndLL = Ten & Twelve; + EXPECT_EQ(AndLL, 0x8); + + APInt AndLR = Ten & getRValue("C", RawDataR); + EXPECT_EQ(AndLR, 0x8); + EXPECT_EQ(AndLR.getRawData(), RawDataR); + + APInt AndRL = getRValue("A", RawDataL) & Twelve; + EXPECT_EQ(AndRL, 0x8); + EXPECT_EQ(AndRL.getRawData(), RawDataL); + + APInt AndRR = getRValue("A", RawDataL) & getRValue("C", RawDataR); + EXPECT_EQ(AndRR, 0x8); + EXPECT_EQ(AndRR.getRawData(), RawDataR); + + // LValue's and constants + APInt AndLK = Ten & 0xc; + EXPECT_EQ(AndLK, 0x8); + + APInt AndKL = 0xa & Twelve; + EXPECT_EQ(AndKL, 0x8); + + // RValue's and constants + APInt AndRK = getRValue("A", RawDataL) & 0xc; + EXPECT_EQ(AndRK, 0x8); + EXPECT_EQ(AndRK.getRawData(), RawDataL); + + APInt AndKR = 0xa & getRValue("C", RawDataR); + EXPECT_EQ(AndKR, 0x8); + EXPECT_EQ(AndKR.getRawData(), RawDataR); + } + + { + // 12 | 10 = 14 + APInt OrLL = Ten | Twelve; + EXPECT_EQ(OrLL, 0xe); + + APInt OrLR = Ten | getRValue("C", RawDataR); + EXPECT_EQ(OrLR, 0xe); + EXPECT_EQ(OrLR.getRawData(), RawDataR); + + APInt OrRL = getRValue("A", RawDataL) | Twelve; + EXPECT_EQ(OrRL, 0xe); + EXPECT_EQ(OrRL.getRawData(), RawDataL); + + APInt OrRR = getRValue("A", RawDataL) | getRValue("C", RawDataR); + EXPECT_EQ(OrRR, 0xe); + EXPECT_EQ(OrRR.getRawData(), RawDataR); + + // LValue's and constants + APInt OrLK = Ten | 0xc; + EXPECT_EQ(OrLK, 0xe); + + APInt OrKL = 0xa | Twelve; + EXPECT_EQ(OrKL, 0xe); + + // RValue's and constants + APInt OrRK = getRValue("A", RawDataL) | 0xc; + EXPECT_EQ(OrRK, 0xe); + EXPECT_EQ(OrRK.getRawData(), RawDataL); + + APInt OrKR = 0xa | getRValue("C", RawDataR); + EXPECT_EQ(OrKR, 0xe); + EXPECT_EQ(OrKR.getRawData(), RawDataR); + } + + { + // 12 ^ 10 = 6 + APInt XorLL = Ten ^ Twelve; + EXPECT_EQ(XorLL, 0x6); + + APInt XorLR = Ten ^ getRValue("C", RawDataR); + EXPECT_EQ(XorLR, 0x6); + EXPECT_EQ(XorLR.getRawData(), RawDataR); + + APInt XorRL = getRValue("A", RawDataL) ^ Twelve; + EXPECT_EQ(XorRL, 0x6); + EXPECT_EQ(XorRL.getRawData(), RawDataL); + + APInt XorRR = getRValue("A", RawDataL) ^ getRValue("C", RawDataR); + EXPECT_EQ(XorRR, 0x6); + EXPECT_EQ(XorRR.getRawData(), RawDataR); + + // LValue's and constants + APInt XorLK = Ten ^ 0xc; + EXPECT_EQ(XorLK, 0x6); + + APInt XorKL = 0xa ^ Twelve; + EXPECT_EQ(XorKL, 0x6); + + // RValue's and constants + APInt XorRK = getRValue("A", RawDataL) ^ 0xc; + EXPECT_EQ(XorRK, 0x6); + EXPECT_EQ(XorRK.getRawData(), RawDataL); + + APInt XorKR = 0xa ^ getRValue("C", RawDataR); + EXPECT_EQ(XorKR, 0x6); + EXPECT_EQ(XorKR.getRawData(), RawDataR); + } +} + TEST(APIntTest, rvalue_invert) { // Lamdba to return an APInt by value, but also provide the raw value of the // allocated data.