From 5ae5d25e38efad1d59ed97d969a5e930b58a5e16 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 14 Apr 2021 08:48:47 -0400 Subject: [PATCH] [ValueTracking] match negative-stepping non-zero recurrence This is pulled out of D100408. This avoids a regression that would be exposed by making the calling code from InstSimplify more efficient. --- llvm/lib/Analysis/ValueTracking.cpp | 11 +++++++---- llvm/unittests/Analysis/ValueTrackingTest.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 2d933489447d..d78acdbb1cd9 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2213,8 +2213,8 @@ static bool rangeMetadataExcludesValue(const MDNode* Ranges, const APInt& Value) return true; } -/// Try to detect a recurrence that monotonically increases from a non-zero -/// starting value. These are common as induction variables. +/// 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) { BinaryOperator *BO = nullptr; Value *Start = nullptr, *Step = nullptr; @@ -2225,10 +2225,13 @@ static bool isNonZeroRecurrence(const PHINode *PN) { switch (BO->getOpcode()) { case Instruction::Add: + // Starting from non-zero and stepping away from zero can never wrap back + // to zero. + // TODO: The constant step requirement is not needed with NUW. return match(Step, m_APInt(StepC)) && ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) || - (BO->hasNoSignedWrap() && StartC->isStrictlyPositive() && - StepC->isNonNegative())); + (BO->hasNoSignedWrap() && + StartC->isNegative() == StepC->isNegative())); case Instruction::Mul: return match(Step, m_APInt(StepC)) && ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) || diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 85678bb66530..99a0f6daa84d 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1191,7 +1191,7 @@ TEST_F(ValueTrackingTest, isNonZeroRecurrence) { )"); 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) {