diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -345,7 +345,7 @@ /// 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::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 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -1912,6 +1912,9 @@ EXPECT_EQ(i260.extractBits(64, 128).getZExtValue(), 0xFFFFFFFFFFFF0000ull); EXPECT_EQ(i260.extractBits(64, 192).getZExtValue(), 0xFFFFFFFFFFFFFFFFull); EXPECT_EQ(i260.extractBits(4, 256).getZExtValue(), 0x000000000000000Full); + + // Zero width insert is a noop. + i31.insertBits(APInt::getZeroWidth(), 1); } TEST(APIntTest, insertBitsUInt64) { @@ -2587,7 +2590,7 @@ EXPECT_EQ(0xFFFFFFFF, val.truncOrSelf(64)); } -TEST(APIntTest, concatMSB) { +TEST(APIntTest, concat) { APInt Int1(4, 0x1ULL); APInt Int3(4, 0x3ULL); @@ -2597,6 +2600,11 @@ 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) {