diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5164,6 +5164,23 @@ return new ICmpInst(Pred, OtherVal, Constant::getNullValue(A->getType())); } + // ((A / -B) == (A / B)) -> ((A / B) == 0) + // if known A != INT_MIN or B != INT_MIN + { + const unsigned OpWidth = Op0->getType()->getScalarSizeInBits(); + APInt SignedMinValue = APInt::getSignedMinValue(OpWidth); + Constant *MinInt = ConstantInt::get(Op0->getType(), SignedMinValue); + if (match(Op0, m_OneUse(m_SDiv(m_Value(A), m_OneUse(m_Neg(m_Value(B)))))) && + match(Op1, m_SDiv(m_Specific(A), m_Specific(B)))) { + // Check if A is known to be != INT_MIN + if (isKnownNonEqual(A, MinInt, DL, &AC, &I, &DT, true)) + return new ICmpInst(Pred, Op1, Constant::getNullValue(A->getType())); + // Check if B is known to be != INT_MIN + if (isKnownNonEqual(B, MinInt, DL, &AC, &I, &DT, true)) + return new ICmpInst(Pred, Op1, Constant::getNullValue(A->getType())); + } + } + // (X&Z) == (Y&Z) -> (X^Y) & Z == 0 if (match(Op0, m_OneUse(m_And(m_Value(A), m_Value(B)))) && match(Op1, m_OneUse(m_And(m_Value(C), m_Value(D))))) { diff --git a/llvm/test/Transforms/InstCombine/icmp-sdiv-sdiv.ll b/llvm/test/Transforms/InstCombine/icmp-sdiv-sdiv.ll --- a/llvm/test/Transforms/InstCombine/icmp-sdiv-sdiv.ll +++ b/llvm/test/Transforms/InstCombine/icmp-sdiv-sdiv.ll @@ -9,10 +9,8 @@ ; CHECK-LABEL: @icmp_sdiv_sdiv_normal_i8( ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ne i8 [[C:%.*]], -128 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[NEGC:%.*]] = sub i8 0, [[C]] -; CHECK-NEXT: [[D1:%.*]] = sdiv i8 [[X:%.*]], [[NEGC]] -; CHECK-NEXT: [[D2:%.*]] = sdiv i8 [[X]], [[C]] -; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[D1]], [[D2]] +; CHECK-NEXT: [[D2:%.*]] = sdiv i8 [[X:%.*]], [[C]] +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[D2]], 0 ; CHECK-NEXT: ret i1 [[C]] ; %precond = icmp ne i8 %C, -128 @@ -28,10 +26,8 @@ ; CHECK-LABEL: @icmp_sdiv_sdiv_normal_i64( ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ne i64 [[C:%.*]], -9223372036854775808 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[NEGC:%.*]] = sub i64 0, [[C]] -; CHECK-NEXT: [[D1:%.*]] = sdiv i64 [[X:%.*]], [[NEGC]] -; CHECK-NEXT: [[D2:%.*]] = sdiv i64 [[X]], [[C]] -; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[D1]], [[D2]] +; CHECK-NEXT: [[D2:%.*]] = sdiv i64 [[X:%.*]], [[C]] +; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[D2]], 0 ; CHECK-NEXT: ret i1 [[C]] ; %precond = icmp ne i64 %C, -9223372036854775808