[llvm] Fix InstCombine variable folding crash (PR #205148)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 5 12:09:49 PDT 2026
https://github.com/rdevshp updated https://github.com/llvm/llvm-project/pull/205148
>From 3e7a9f17fee3c30b0a4c616ed5f437d5b6dfacc7 Mon Sep 17 00:00:00 2001
From: rdevshp <rdevshp at gmail.com>
Date: Mon, 22 Jun 2026 17:12:41 +0000
Subject: [PATCH 1/3] Fix InstCombine variable folding crash
---
.../InstCombine/InstCombineShifts.cpp | 11 +++++----
...e-length-signext-after-high-bit-extract.ll | 23 +++++++++++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 605d80f2be7de..9de75409af00b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1760,10 +1760,13 @@ InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
// Check that constant C is a splat of the element-wise bitwidth of V.
auto BitWidthSplat = [](Constant *C, Value *V) {
- return match(
- C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
- APInt(C->getType()->getScalarSizeInBits(),
- V->getType()->getScalarSizeInBits())));
+ auto CBitWidth = C->getType()->getScalarSizeInBits();
+ auto VBitWidth = V->getType()->getScalarSizeInBits();
+ if (!llvm::isUIntN(CBitWidth, VBitWidth))
+ return false;
+
+ return match(C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
+ APInt(CBitWidth, VBitWidth)));
};
// It should look like variable-length sign-extension on the outside:
diff --git a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
index ccccafdf5f3c7..faa8a7df81c1e 100644
--- a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
+++ b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
@@ -1150,3 +1150,26 @@ define i32 @bitwidth_does_not_fit(i3 %arg) {
%inc = add i32 %shr, 1
ret i32 %inc
}
+
+define i16 @shift_count_bitwidth_does_not_fit(i16 %x, i4 %n) {
+; CHECK-LABEL: @shift_count_bitwidth_does_not_fit(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[HIGHBITS:%.*]] = lshr i16 [[X:%.*]], 1
+; CHECK-NEXT: [[SUB1:%.*]] = sub i4 0, [[N:%.*]]
+; CHECK-NEXT: [[Z1:%.*]] = zext i4 [[SUB1]] to i16
+; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[HIGHBITS]], [[Z1]]
+; CHECK-NEXT: [[SUB2:%.*]] = sub i4 0, [[N]]
+; CHECK-NEXT: [[Z2:%.*]] = zext i4 [[SUB2]] to i16
+; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 [[SHL]], [[Z2]]
+; CHECK-NEXT: ret i16 [[ASHR]]
+;
+entry:
+ %highbits = lshr i16 %x, 1
+ %sub1 = sub i4 0, %n
+ %z1 = zext i4 %sub1 to i16
+ %shl = shl i16 %highbits, %z1
+ %sub2 = sub i4 0, %n
+ %z2 = zext i4 %sub2 to i16
+ %ashr = ashr i16 %shl, %z2
+ ret i16 %ashr
+}
>From 90f409ac731073e4d85519689fce7ed5d1a738f8 Mon Sep 17 00:00:00 2001
From: rdevshp <rdevshp at gmail.com>
Date: Tue, 23 Jun 2026 19:36:27 +0000
Subject: [PATCH 2/3] Remove entry label from the test case
shift_count_bitwidth_does_not_fit
---
...onditional-variable-length-signext-after-high-bit-extract.ll | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
index faa8a7df81c1e..6b33a4dcc3768 100644
--- a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
+++ b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
@@ -1153,7 +1153,6 @@ define i32 @bitwidth_does_not_fit(i3 %arg) {
define i16 @shift_count_bitwidth_does_not_fit(i16 %x, i4 %n) {
; CHECK-LABEL: @shift_count_bitwidth_does_not_fit(
-; CHECK-NEXT: entry:
; CHECK-NEXT: [[HIGHBITS:%.*]] = lshr i16 [[X:%.*]], 1
; CHECK-NEXT: [[SUB1:%.*]] = sub i4 0, [[N:%.*]]
; CHECK-NEXT: [[Z1:%.*]] = zext i4 [[SUB1]] to i16
@@ -1163,7 +1162,6 @@ define i16 @shift_count_bitwidth_does_not_fit(i16 %x, i4 %n) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 [[SHL]], [[Z2]]
; CHECK-NEXT: ret i16 [[ASHR]]
;
-entry:
%highbits = lshr i16 %x, 1
%sub1 = sub i4 0, %n
%z1 = zext i4 %sub1 to i16
>From 810e244e6b2550b276882c7b676279cfa1328092 Mon Sep 17 00:00:00 2001
From: rdevshp <rdevshp at gmail.com>
Date: Sun, 5 Jul 2026 19:07:51 +0000
Subject: [PATCH 3/3] use m_SpecificIntAllowPoison(uint64_t V) instead
---
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 9de75409af00b..241bc3bba51c2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1760,13 +1760,8 @@ InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
// Check that constant C is a splat of the element-wise bitwidth of V.
auto BitWidthSplat = [](Constant *C, Value *V) {
- auto CBitWidth = C->getType()->getScalarSizeInBits();
- auto VBitWidth = V->getType()->getScalarSizeInBits();
- if (!llvm::isUIntN(CBitWidth, VBitWidth))
- return false;
-
- return match(C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
- APInt(CBitWidth, VBitWidth)));
+ return match(C,
+ m_SpecificIntAllowPoison(V->getType()->getScalarSizeInBits()));
};
// It should look like variable-length sign-extension on the outside:
More information about the llvm-commits
mailing list