Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -3637,7 +3637,9 @@ } // icmp eq|ne X, Y -> false|true if X != Y - if (ICmpInst::isEquality(Pred) && + // This is potentially expensive, and we have already computedKnownBits for + // compares with 0 above here, so only try this for a non-zero compare. + if (ICmpInst::isEquality(Pred) && !match(RHS, m_Zero()) && isKnownNonEqual(LHS, RHS, Q.DL, Q.AC, Q.CxtI, Q.DT, Q.IIQ.UseInstrInfo)) { return Pred == ICmpInst::ICMP_NE ? getTrue(ITy) : getFalse(ITy); } Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -2213,9 +2213,9 @@ return true; } +/// Try to detect a recurrence that monotonically increases/decreases from a +/// non-zero starting value. These are common as induction variables. static bool isNonZeroRecurrence(const PHINode *PN) { - // Try and detect a recurrence that monotonically increases from a - // starting value, as these are common as induction variables. BinaryOperator *BO = nullptr; Value *Start = nullptr, *Step = nullptr; const APInt *StartC, *StepC; @@ -2225,11 +2225,19 @@ switch (BO->getOpcode()) { case Instruction::Add: - return match(Step, m_APInt(StepC)) && - ((BO->hasNoUnsignedWrap() && !StartC->isNullValue() && - !StepC->isNullValue()) || - (BO->hasNoSignedWrap() && StartC->isStrictlyPositive() && - StepC->isNonNegative())); + if (!match(Step, m_APInt(StepC))) + return false; + if (BO->hasNoUnsignedWrap()) { + if (!StartC->isNullValue() && !StepC->isNullValue()) + return true; + } + if (BO->hasNoSignedWrap()) { + // Starting from non-zero and stepping away from zero can never wrap back + // to zero. + if (!StartC->isNullValue() && StartC->isNegative() == StepC->isNegative()) + return true; + } + return false; case Instruction::Mul: return !StartC->isNullValue() && match(Step, m_APInt(StepC)) && ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) || Index: llvm/unittests/Analysis/ValueTrackingTest.cpp =================================================================== --- llvm/unittests/Analysis/ValueTrackingTest.cpp +++ llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1191,7 +1191,7 @@ )"); DataLayout DL = M->getDataLayout(); AssumptionCache AC(*F); - EXPECT_FALSE(isKnownNonZero(A, DL, 0, &AC, CxtI)); + EXPECT_TRUE(isKnownNonZero(A, DL, 0, &AC, CxtI)); } TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) {