From cc697fc292b0a405eaa42c6c8e5f117ba4f7d73b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 4 Oct 2021 21:33:51 -0700 Subject: [PATCH] [APInt] Make insertBits and concat work with zero width APInts. These should both clearly work with our current model for zero width integers, but don't until now! Differential Revision: https://reviews.llvm.org/D111113 --- llvm/lib/Support/APInt.cpp | 8 ++++++-- llvm/unittests/ADT/APIntTest.cpp | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 9a22ccb..67ea57c 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -345,7 +345,7 @@ void APInt::flipAllBitsSlowCase() { /// In the slow case, we know the result is large. APInt APInt::concatSlowCase(const APInt &NewLSB) const { unsigned NewWidth = getBitWidth() + NewLSB.getBitWidth(); - APInt Result = NewLSB.zext(NewWidth); + APInt Result = NewLSB.zextOrSelf(NewWidth); Result.insertBits(*this, NewLSB.getBitWidth()); return Result; } @@ -360,9 +360,13 @@ void APInt::flipBit(unsigned bitPosition) { void APInt::insertBits(const APInt &subBits, unsigned bitPosition) { unsigned subBitWidth = subBits.getBitWidth(); - assert(0 < subBitWidth && (subBitWidth + bitPosition) <= BitWidth && + assert(subBitWidth >= 0 && (subBitWidth + bitPosition) <= BitWidth && "Illegal bit insertion"); + // inserting no bits is a noop. + if (subBitWidth == 0) + return; + // Insertion is a direct copy. if (subBitWidth == BitWidth) { *this = subBits; diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index fe7a231..59a8f4c 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -1874,6 +1874,10 @@ TEST(APIntTest, insertBits) { i63.insertBits(iSrc, 4); EXPECT_EQ(static_cast(0x012345600123456Full), i63.getSExtValue()); + // Zero width insert is a noop. + i31.insertBits(APInt::getZeroWidth(), 1); + EXPECT_EQ(static_cast(0x00123456ull), i31.getSExtValue()); + // Insert single word src into one word of dst. APInt i120(120, UINT64_MAX, true); i120.insertBits(iSrc, 8); @@ -2587,7 +2591,7 @@ TEST(APIntTest, truncOrSelf) { EXPECT_EQ(0xFFFFFFFF, val.truncOrSelf(64)); } -TEST(APIntTest, concatMSB) { +TEST(APIntTest, concat) { APInt Int1(4, 0x1ULL); APInt Int3(4, 0x3ULL); @@ -2597,6 +2601,11 @@ TEST(APIntTest, concatMSB) { APInt I64(64, 0x3ULL); EXPECT_EQ(I64, I64.concat(I64).lshr(64).trunc(64)); + + APInt I65(65, 0x3ULL); + APInt I0 = APInt::getZeroWidth(); + EXPECT_EQ(I65, I65.concat(I0)); + EXPECT_EQ(I65, I0.concat(I65)); } TEST(APIntTest, multiply) { -- 2.7.4