Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -2457,12 +2457,21 @@ std::swap(Start, Induction); if (ConstantInt *C = dyn_cast(Start)) { if (!C->isZero() && !C->isNegative()) { - ConstantInt *X; - if (Q.IIQ.UseInstrInfo && - (match(Induction, m_NSWAdd(m_Specific(PN), m_ConstantInt(X))) || - match(Induction, m_NUWAdd(m_Specific(PN), m_ConstantInt(X)))) && - !X->isNegative()) - return true; + BinaryOperator *BO = nullptr; + Value *R = nullptr, *L = nullptr; + if (Q.IIQ.UseInstrInfo && matchSimpleRecurrence(PN, BO, R, L)) { + if (auto StepCst = dyn_cast(L)) { + if (BO->getOpcode() == Instruction::Add && + (BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) && + !StepCst->isNegative()) + return true; + if (BO->getOpcode() == Instruction::Mul && !C->isOne() && + (BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) && + !StepCst->isNegative() && !StepCst->isZero() && + !StepCst->isOne()) + return true; + } + } } } } Index: llvm/test/Analysis/ValueTracking/monotonic-phi.ll =================================================================== --- llvm/test/Analysis/ValueTracking/monotonic-phi.ll +++ llvm/test/Analysis/ValueTracking/monotonic-phi.ll @@ -47,3 +47,35 @@ ; CHECK: ret i1 false ret i1 %cmp } + +; CHECK-LABEL: @test4 +define i1 @test4(i8 %p, i8* %pq, i8 %n, i8 %r) { +entry: + br label %loop +loop: + %A = phi i8 [ 2, %entry ], [ %next, %loop ] + %next = mul nsw i8 %A, 2 + %cmp1 = icmp eq i8 %A, %n + br i1 %cmp1, label %exit, label %loop +exit: + %add = or i8 %A, %r + %cmp = icmp eq i8 %add, 0 + ; CHECK: ret i1 false + ret i1 %cmp +} + +; CHECK-LABEL: @test5 +define i1 @test5(i8 %p, i8* %pq, i8 %n, i8 %r) { +entry: + br label %loop +loop: + %A = phi i8 [ 2, %entry ], [ %next, %loop ] + %next = mul i8 %A, 2 + %cmp1 = icmp eq i8 %A, %n + br i1 %cmp1, label %exit, label %loop +exit: + %add = or i8 %A, %r + %cmp = icmp eq i8 %add, 0 + ; CHECK-NOT: ret i1 false + ret i1 %cmp +}