[llvm] a849f52 - [InstCombine] Fix assertion failure in `foldVariableSignZeroExtensionOfVariableHighBitExtract` (#205148)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 20:59:24 PDT 2026


Author: rdevshp
Date: 2026-07-07T11:59:19+08:00
New Revision: a849f52b7930ead34ce6337763cff9977f5f61aa

URL: https://github.com/llvm/llvm-project/commit/a849f52b7930ead34ce6337763cff9977f5f61aa
DIFF: https://github.com/llvm/llvm-project/commit/a849f52b7930ead34ce6337763cff9977f5f61aa.diff

LOG: [InstCombine] Fix assertion failure in `foldVariableSignZeroExtensionOfVariableHighBitExtract` (#205148)

This PR fixes crash for the following program:
```
define i16 @d(i16 %x, i4 %n) {
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
}
```
when running `opt -passes=instcombine prog.ll -S`.

Assisted-by: Codex

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 605d80f2be7de..241bc3bba51c2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1760,10 +1760,8 @@ 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())));
+    return match(C,
+                 m_SpecificIntAllowPoison(V->getType()->getScalarSizeInBits()));
   };
 
   // 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..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
@@ -1150,3 +1150,24 @@ 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:    [[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]]
+;
+  %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
+}


        


More information about the llvm-commits mailing list