Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1819,14 +1819,18 @@ // First, find an or'd pair of opposite shifts with the same shifted operand: // or (lshr ShVal, ShAmt0), (shl ShVal, ShAmt1) - Value *Or0 = Or.getOperand(0), *Or1 = Or.getOperand(1); + BinaryOperator *Or0, *Or1; + if (!match(Or.getOperand(0), m_BinOp(Or0)) || + !match(Or.getOperand(1), m_BinOp(Or1))) + return nullptr; + Value *ShVal, *ShAmt0, *ShAmt1; if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal), m_Value(ShAmt0)))) || !match(Or1, m_OneUse(m_LogicalShift(m_Specific(ShVal), m_Value(ShAmt1))))) return nullptr; - auto ShiftOpcode0 = cast(Or0)->getOpcode(); - auto ShiftOpcode1 = cast(Or1)->getOpcode(); + BinaryOperator::BinaryOps ShiftOpcode0 = Or0->getOpcode(); + BinaryOperator::BinaryOps ShiftOpcode1 = Or1->getOpcode(); if (ShiftOpcode0 == ShiftOpcode1) return nullptr; Index: llvm/trunk/test/Transforms/InstCombine/rotate.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/rotate.ll +++ llvm/trunk/test/Transforms/InstCombine/rotate.ll @@ -689,3 +689,17 @@ ret i24 %r } +; Test that the transform doesn't crash when there's an "or" with a ConstantExpr operand. + +@external_global = external global i8 + +define i32 @rotl_constant_expr(i32 %shamt) { +; CHECK-LABEL: @rotl_constant_expr( +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 ptrtoint (i8* @external_global to i32), [[SHAMT:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i32 [[SHR]], shl (i32 ptrtoint (i8* @external_global to i32), i32 11) +; CHECK-NEXT: ret i32 [[R]] +; + %shr = lshr i32 ptrtoint (i8* @external_global to i32), %shamt + %r = or i32 %shr, shl (i32 ptrtoint (i8* @external_global to i32), i32 11) + ret i32 %r +}