diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 31263bb7de8..bd42af15da3 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1948,9 +1948,15 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, if (!CI2->isZero()) Upper = NegOne.udiv(CI2->getValue()) + 1; } else if (match(LHS, m_SDiv(m_ConstantInt(CI2), m_Value()))) { - // 'sdiv CI2, x' produces [-|CI2|, |CI2|]. - Upper = CI2->getValue().abs() + 1; - Lower = (-Upper) + 1; + if (CI2->isMinSignedValue()) { + // 'sdiv INT_MIN, x' produces [INT_MIN, INT_MIN / -2]. + Lower = CI2->getValue(); + Upper = Lower.lshr(1) + 1; + } else { + // 'sdiv CI2, x' produces [-|CI2|, |CI2|]. + Upper = CI2->getValue().abs() + 1; + Lower = (-Upper) + 1; + } } else if (match(LHS, m_SDiv(m_Value(), m_ConstantInt(CI2)))) { // 'sdiv x, CI2' produces [INT_MIN / CI2, INT_MAX / CI2]. APInt IntMin = APInt::getSignedMinValue(Width); diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index 89fd6362d78..7d0cd9c5878 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -902,3 +902,14 @@ define i1 @icmp_ne_const(i32 %a) nounwind { ; CHECK-LABEL: @icmp_ne_const ; CHECK-NEXT: ret i1 true } + +define i1 @icmp_sdiv_int_min(i32 %a) { + %div = sdiv i32 -2147483648, %a + %cmp = icmp ne i32 %div, -1073741824 + ret i1 %cmp + +; CHECK-LABEL: @icmp_sdiv_int_min +; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 -2147483648, %a +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[DIV]], -1073741824 +; CHECK-NEXT: ret i1 [[CMP]] +}