[APInt] Add integer API bor bitwise operations.

Summary: As per title. I ran into that limitation of the API doing some other work, so I though that'd be a nice addition.

Reviewers: jroelofs, compnerd, majnemer

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D29503

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294063 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Amaury Sechet 2017-02-03 22:54:41 +00:00
parent 66d69563f7
commit 21b9ce0d3d
3 changed files with 116 additions and 0 deletions

View File

@ -698,6 +698,13 @@ public:
/// \returns *this after ANDing with RHS.
APInt &operator&=(const APInt &RHS);
/// \brief Bitwise AND assignment operator.
///
/// Performs a bitwise AND operation on this APInt and RHS. RHS is
/// logically zero-extended or truncated to match the bit-width of
/// the LHS.
APInt &operator&=(uint64_t RHS);
/// \brief Bitwise OR assignment operator.
///
/// Performs a bitwise OR operation on this APInt and RHS. The result is
@ -729,6 +736,21 @@ public:
/// \returns *this after XORing with RHS.
APInt &operator^=(const APInt &RHS);
/// \brief Bitwise XOR assignment operator.
///
/// Performs a bitwise XOR operation on this APInt and RHS. RHS is
/// logically zero-extended or truncated to match the bit-width of
/// the LHS.
APInt &operator^=(uint64_t RHS) {
if (isSingleWord()) {
VAL ^= RHS;
clearUnusedBits();
} else {
pVal[0] ^= RHS;
}
return *this;
}
/// \brief Multiplication assignment operator.
///
/// Multiplies this APInt by RHS and assigns the result to *this.
@ -1723,6 +1745,36 @@ inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
inline APInt operator&(APInt a, uint64_t RHS) {
a &= RHS;
return a;
}
inline APInt operator&(uint64_t LHS, APInt b) {
b &= LHS;
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;
}
inline APInt operator^(APInt a, uint64_t RHS) {
a ^= RHS;
return a;
}
inline APInt operator^(uint64_t LHS, APInt b) {
b ^= LHS;
return b;
}
inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
I.print(OS, true);
return OS;

View File

@ -424,6 +424,18 @@ APInt& APInt::operator&=(const APInt& RHS) {
return *this;
}
APInt &APInt::operator&=(uint64_t RHS) {
if (isSingleWord()) {
VAL &= RHS;
return *this;
}
pVal[0] &= RHS;
unsigned numWords = getNumWords();
for (unsigned i = 1; i < numWords; ++i)
pVal[i] = 0;
return *this;
}
APInt& APInt::operator|=(const APInt& RHS) {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord()) {

View File

@ -446,6 +446,58 @@ TEST(APIntTest, compareLargeIntegers) {
EXPECT_TRUE(!MinusTwo.slt(MinusTwo));
}
TEST(APIntTest, binaryOpsWithRawIntegers) {
// Single word check.
uint64_t E1 = 0x2CA7F46BF6569915ULL;
APInt A1(64, E1);
EXPECT_EQ(A1 & E1, E1);
EXPECT_EQ(A1 & 0, 0);
EXPECT_EQ(A1 & 1, 1);
EXPECT_EQ(A1 & 5, 5);
EXPECT_EQ(A1 & UINT64_MAX, E1);
EXPECT_EQ(A1 | E1, E1);
EXPECT_EQ(A1 | 0, E1);
EXPECT_EQ(A1 | 1, E1);
EXPECT_EQ(A1 | 2, E1 | 2);
EXPECT_EQ(A1 | UINT64_MAX, UINT64_MAX);
EXPECT_EQ(A1 ^ E1, 0);
EXPECT_EQ(A1 ^ 0, E1);
EXPECT_EQ(A1 ^ 1, E1 ^ 1);
EXPECT_EQ(A1 ^ 7, E1 ^ 7);
EXPECT_EQ(A1 ^ UINT64_MAX, ~E1);
// Multiword check.
uint64_t N = 0xEB6EB136591CBA21ULL;
integerPart E2[4] = {
N,
0x7B9358BD6A33F10AULL,
0x7E7FFA5EADD8846ULL,
0x305F341CA00B613DULL
};
APInt A2(integerPartWidth*4, E2);
EXPECT_EQ(A2 & N, N);
EXPECT_EQ(A2 & 0, 0);
EXPECT_EQ(A2 & 1, 1);
EXPECT_EQ(A2 & 5, 1);
EXPECT_EQ(A2 & UINT64_MAX, N);
EXPECT_EQ(A2 | N, A2);
EXPECT_EQ(A2 | 0, A2);
EXPECT_EQ(A2 | 1, A2);
EXPECT_EQ(A2 | 2, A2 + 2);
EXPECT_EQ(A2 | UINT64_MAX, A2 - N + UINT64_MAX);
EXPECT_EQ(A2 ^ N, A2 - N);
EXPECT_EQ(A2 ^ 0, A2);
EXPECT_EQ(A2 ^ 1, A2 - 1);
EXPECT_EQ(A2 ^ 7, A2 + 5);
EXPECT_EQ(A2 ^ UINT64_MAX, A2 - N + ~N);
}
TEST(APIntTest, rvalue_arithmetic) {
// Test all combinations of lvalue/rvalue lhs/rhs of add/sub