Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp @@ -2280,6 +2280,28 @@ } } + // 0 - (zext X) pred C + if (!CmpInst::isUnsigned(Pred) && 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 (Pred == ICmpInst::ICMP_EQ) + return ConstantInt::getFalse(RHSC->getContext()); + if (Pred == ICmpInst::ICMP_NE) + return ConstantInt::getTrue(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: llvm/trunk/test/Transforms/InstSimplify/compare.ll =================================================================== --- llvm/trunk/test/Transforms/InstSimplify/compare.ll +++ llvm/trunk/test/Transforms/InstSimplify/compare.ll @@ -757,3 +757,63 @@ ; 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_sge +; CHECK-NEXT: ret i1 false +} + +define i1 @compare_always_false_eq(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp eq i32 %2, 1 + ret i1 %3 + +; CHECK-LABEL: @compare_always_false_eq +; CHECK-NEXT: ret i1 false +} + +define i1 @compare_always_false_ne(i16 %a) { + %1 = zext i16 %a to i32 + %2 = sub nsw i32 0, %1 + %3 = icmp ne i32 %2, 1 + ret i1 %3 + +; CHECK-LABEL: @compare_always_false_ne +; CHECK-NEXT: ret i1 true +}