summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp3
-rw-r--r--llvm/test/Transforms/InstCombine/shift-logic.ll17
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
+}
OpenPOWER on IntegriCloud