[llvm] Fix APInt::concat for zero-width operands (PR #207475)

Yi Zhang via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 4 17:06:20 PDT 2026


https://github.com/cathyzhyi updated https://github.com/llvm/llvm-project/pull/207475

>From 7711c68170681858489c60cd26d99cda06eb9c61 Mon Sep 17 00:00:00 2001
From: Yi Zhang <cathyzhyi at google.com>
Date: Fri, 3 Jul 2026 20:36:46 -0400
Subject: [PATCH] [Support][APint] Fix concat for zero-width operands

APInt::concat triggered undefined behavior (invalid shift exponent) when
concatenating a zero-width operand with a 64-bit operand on the fast path
(combined width <= 64). For example, `I0.concat(I64)` resulted in
`U.VAL << 64`, which is UB.
Fix by checking for zero-width operands early and returning the other
operand. Added regression tests to `APIntTest.cpp`.
---
 llvm/include/llvm/ADT/APInt.h    | 4 ++++
 llvm/unittests/ADT/APIntTest.cpp | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 026efbe866a93..bc14d76fa1985 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -952,6 +952,10 @@ class [[nodiscard]] APInt {
   /// equivalent to:
   ///   (this->zext(NewWidth) << NewLSB.getBitWidth()) | NewLSB.zext(NewWidth)
   APInt concat(const APInt &NewLSB) const {
+    if (getBitWidth() == 0)
+      return NewLSB;
+    if (NewLSB.getBitWidth() == 0)
+      return *this;
     /// If the result will be small, then both the merged values are small.
     unsigned NewWidth = getBitWidth() + NewLSB.getBitWidth();
     if (NewWidth <= APINT_BITS_PER_WORD)
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 0eea32480d0bf..72b195e275a1c 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -3132,6 +3132,8 @@ TEST(APIntTest, concat) {
 
   APInt I65(65, 0x3ULL);
   APInt I0 = APInt::getZeroWidth();
+  EXPECT_EQ(I64, I64.concat(I0));
+  EXPECT_EQ(I64, I0.concat(I64));
   EXPECT_EQ(I65, I65.concat(I0));
   EXPECT_EQ(I65, I0.concat(I65));
 }



More information about the llvm-commits mailing list