diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 9a22ccb97f4990..67ea57c8ee599d 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 fe7a231d33fe26..59a8f4cd0f8f16 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) {