Skip to content

Commit 5d67d81

Browse files
committed
[InstCombine] prevent crashing/assert on shift constant expression (PR44028)
The binary operator cast implies an instruction, but the matcher for shift does not: https://bugs.llvm.org/show_bug.cgi?id=44028
1 parent 1b0efe2 commit 5d67d81

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I,
319319
// TODO: Remove the one-use check if the other logic operand (Y) is constant.
320320
Value *X, *Y;
321321
auto matchFirstShift = [&](Value *V) {
322-
return match(V, m_OneUse(m_Shift(m_Value(X), m_APInt(C0)))) &&
322+
return !isa<ConstantExpr>(V) &&
323+
match(V, m_OneUse(m_Shift(m_Value(X), m_APInt(C0)))) &&
323324
cast<BinaryOperator>(V)->getOpcode() == ShiftOpcode &&
324325
(*C0 + *C1).ult(Ty->getScalarSizeInBits());
325326
};

llvm/test/Transforms/InstCombine/shift-logic.ll

+17
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,20 @@ define i32 @lshr_or_extra_use(i32 %x, i32 %y, i32* %p) {
169169
%sh1 = lshr i32 %r, 7
170170
ret i32 %sh1
171171
}
172+
173+
; Avoid crashing on constant expressions.
174+
175+
@g = external global i32
176+
177+
define i32 @PR44028(i32 %x) {
178+
; CHECK-LABEL: @PR44028(
179+
; CHECK-NEXT: [[SH1:%.*]] = ashr exact i32 [[X:%.*]], 16
180+
; CHECK-NEXT: [[T0:%.*]] = xor i32 [[SH1]], shl (i32 ptrtoint (i32* @g to i32), i32 16)
181+
; CHECK-NEXT: [[T27:%.*]] = ashr exact i32 [[T0]], 16
182+
; CHECK-NEXT: ret i32 [[T27]]
183+
;
184+
%sh1 = ashr exact i32 %x, 16
185+
%t0 = xor i32 %sh1, shl (i32 ptrtoint (i32* @g to i32), i32 16)
186+
%t27 = ashr exact i32 %t0, 16
187+
ret i32 %t27
188+
}

0 commit comments

Comments
 (0)