diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2017-03-10 13:44:32 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2017-03-10 13:44:32 +0000 |
commit | 943d3e07f89e81d1682313e61f12b365cc060281 (patch) | |
tree | 575a2ce6dc9ed5e72d110447fc421bef4710dc90 /unittests | |
parent | 56582e5d88cf1bf90ec1b2df1e97e1850af25e44 (diff) |
[APInt] Add APInt::insertBits() method to insert an APInt into a larger APInt
We currently have to insert bits via a temporary variable of the same size as the target with various shift/mask stages, resulting in further temporary variables, all of which require the allocation of memory for large APInts (MaskSizeInBits > 64).
This is another of the compile time issues identified in PR32037 (see also D30265).
This patch adds the APInt::insertBits() helper method which avoids the temporary memory allocation and masks/inserts the raw bits directly into the target.
Differential Revision: https://reviews.llvm.org/D30780
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297458 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ADT/APIntTest.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index f1cf28f993e..3e30d921f1e 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -1647,6 +1647,59 @@ TEST(APIntTest, reverseBits) { } } +TEST(APIntTest, insertBits) { + APInt iSrc(31, 0x00123456); + + // Direct copy. + APInt i31(31, 0x76543210ull); + i31.insertBits(iSrc, 0); + EXPECT_EQ(static_cast<int64_t>(0x00123456ull), i31.getSExtValue()); + + // Single word src/dst insertion. + APInt i63(63, 0x01234567FFFFFFFFull); + i63.insertBits(iSrc, 4); + EXPECT_EQ(static_cast<int64_t>(0x012345600123456Full), i63.getSExtValue()); + + // Insert single word src into one word of dst. + APInt i120(120, UINT64_MAX, true); + i120.insertBits(iSrc, 8); + EXPECT_EQ(static_cast<int64_t>(0xFFFFFF80123456FFull), i120.getSExtValue()); + + // Insert single word src into two words of dst. + APInt i127(127, UINT64_MAX, true); + i127.insertBits(iSrc, 48); + EXPECT_EQ(i127.extractBits(64, 0).getZExtValue(), 0x3456FFFFFFFFFFFF); + EXPECT_EQ(i127.extractBits(63, 64).getZExtValue(), 0x7FFFFFFFFFFF8012); + + // Insert on word boundaries. + APInt i128(128, 0); + i128.insertBits(APInt(64, UINT64_MAX, true), 0); + i128.insertBits(APInt(64, UINT64_MAX, true), 64); + EXPECT_EQ(-1, i128.getSExtValue()); + + APInt i256(256, UINT64_MAX, true); + i256.insertBits(APInt(65, 0), 0); + i256.insertBits(APInt(69, 0), 64); + i256.insertBits(APInt(128, 0), 128); + EXPECT_EQ(0u, i256.getSExtValue()); + + APInt i257(257, 0); + i257.insertBits(APInt(96, UINT64_MAX, true), 64); + EXPECT_EQ(i257.extractBits(64, 0).getZExtValue(), 0x0000000000000000); + EXPECT_EQ(i257.extractBits(64, 64).getZExtValue(), 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(i257.extractBits(64, 128).getZExtValue(), 0x00000000FFFFFFFF); + EXPECT_EQ(i257.extractBits(65, 192).getZExtValue(), 0x0000000000000000); + + // General insertion. + APInt i260(260, UINT64_MAX, true); + i260.insertBits(APInt(129, 1ull << 48), 15); + EXPECT_EQ(i260.extractBits(64, 0).getZExtValue(), 0x8000000000007FFF); + EXPECT_EQ(i260.extractBits(64, 64).getZExtValue(), 0x0000000000000000); + EXPECT_EQ(i260.extractBits(64, 128).getZExtValue(), 0xFFFFFFFFFFFF0000); + EXPECT_EQ(i260.extractBits(64, 192).getZExtValue(), 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(i260.extractBits(4, 256).getZExtValue(), 0x000000000000000F); +} + TEST(APIntTest, extractBits) { APInt i32(32, 0x1234567); EXPECT_EQ(0x3456, i32.extractBits(16, 4)); |