Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -2280,6 +2280,24 @@ } } + // 0 - (zext X) pred C + if (match(LHS, m_Neg(m_ZExt(m_Value())))) { + if (ConstantInt *RHSC = dyn_cast(RHS)) { + if (RHSC->getValue().isStrictlyPositive()) { + if (Pred == ICmpInst::ICMP_SLT) + return ConstantInt::getTrue(RHSC->getContext()); + if (Pred == ICmpInst::ICMP_SGE) + return ConstantInt::getFalse(RHSC->getContext()); + } + if (RHSC->getValue().isNonNegative()) { + if (Pred == ICmpInst::ICMP_SLE) + return ConstantInt::getTrue(RHSC->getContext()); + if (Pred == ICmpInst::ICMP_SGT) + return ConstantInt::getFalse(RHSC->getContext()); + } + } + } + // icmp pred (urem X, Y), Y if (LBO && match(LBO, m_URem(m_Value(), m_Specific(RHS)))) { bool KnownNonNegative, KnownNegative; Index: test/Transforms/InstSimplify/compare.ll =================================================================== --- test/Transforms/InstSimplify/compare.ll +++ test/Transforms/InstSimplify/compare.ll @@ -757,3 +757,43 @@ ; CHECK-LABEL: @vectorselectfold ; CHECK-NEXT: ret <4 x i8> %a } + +define i1 @compare_always_true_slt(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp slt i32 %2, 1 + ret i1 %3 + +; CHECK-LABEL: @compare_always_true_slt +; CHECK-NEXT: ret i1 true +} + +define i1 @compare_always_true_sle(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp sle i32 %2, 0 + ret i1 %3 + +; CHECK-LABEL: @compare_always_true_sle +; CHECK-NEXT: ret i1 true +} + +define i1 @compare_always_false_sgt(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp sgt i32 %2, 0 + ret i1 %3 + +; CHECK-LABEL: @compare_always_false_sgt +; CHECK-NEXT: ret i1 false +} + +define i1 @compare_always_false_sge(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp sge i32 %2, 1 + ret i1 %3 + +; CHECK-LABEL: @compare_always_false +; CHECK-NEXT: ret i1 false +}