summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ADT
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2017-03-10 13:44:32 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2017-03-10 13:44:32 +0000
commitb02667c469493e8f1eee4601d175942c9e80c73d (patch)
treeca9f54e6c64afb485db66deae194e50ae5dc57bb /llvm/unittests/ADT
parent7090d145e8eb0164e5862321e76ecfc1736dd741 (diff)
downloadbcm5719-llvm-b02667c469493e8f1eee4601d175942c9e80c73d.tar.gz
bcm5719-llvm-b02667c469493e8f1eee4601d175942c9e80c73d.zip
[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 llvm-svn: 297458
Diffstat (limited to 'llvm/unittests/ADT')
-rw-r--r--llvm/unittests/ADT/APIntTest.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index f1cf28f993e..3e30d921f1e 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/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));
OpenPOWER on IntegriCloud