diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/shift-logic.ll | 17 |
2 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index f35a6ce2d93..fbff5dd4a8c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -319,7 +319,8 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I, // TODO: Remove the one-use check if the other logic operand (Y) is constant. Value *X, *Y; auto matchFirstShift = [&](Value *V) { - return match(V, m_OneUse(m_Shift(m_Value(X), m_APInt(C0)))) && + return !isa<ConstantExpr>(V) && + match(V, m_OneUse(m_Shift(m_Value(X), m_APInt(C0)))) && cast<BinaryOperator>(V)->getOpcode() == ShiftOpcode && (*C0 + *C1).ult(Ty->getScalarSizeInBits()); }; diff --git a/llvm/test/Transforms/InstCombine/shift-logic.ll b/llvm/test/Transforms/InstCombine/shift-logic.ll index 453463f46fc..d0d06a38727 100644 --- a/llvm/test/Transforms/InstCombine/shift-logic.ll +++ b/llvm/test/Transforms/InstCombine/shift-logic.ll @@ -169,3 +169,20 @@ define i32 @lshr_or_extra_use(i32 %x, i32 %y, i32* %p) { %sh1 = lshr i32 %r, 7 ret i32 %sh1 } + +; Avoid crashing on constant expressions. + +@g = external global i32 + +define i32 @PR44028(i32 %x) { +; CHECK-LABEL: @PR44028( +; CHECK-NEXT: [[SH1:%.*]] = ashr exact i32 [[X:%.*]], 16 +; CHECK-NEXT: [[T0:%.*]] = xor i32 [[SH1]], shl (i32 ptrtoint (i32* @g to i32), i32 16) +; CHECK-NEXT: [[T27:%.*]] = ashr exact i32 [[T0]], 16 +; CHECK-NEXT: ret i32 [[T27]] +; + %sh1 = ashr exact i32 %x, 16 + %t0 = xor i32 %sh1, shl (i32 ptrtoint (i32* @g to i32), i32 16) + %t27 = ashr exact i32 %t0, 16 + ret i32 %t27 +} |