[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.
This commit is contained in:
Sanjay Patel 2021-04-14 08:48:47 -04:00
parent 856c49d79c
commit 5ae5d25e38
2 changed files with 8 additions and 5 deletions

View File

@ -2213,8 +2213,8 @@ static bool rangeMetadataExcludesValue(const MDNode* Ranges, const APInt& Value)
return true; return true;
} }
/// Try to detect a recurrence that monotonically increases from a non-zero /// Try to detect a recurrence that monotonically increases/decreases from a
/// starting value. These are common as induction variables. /// non-zero starting value. These are common as induction variables.
static bool isNonZeroRecurrence(const PHINode *PN) { static bool isNonZeroRecurrence(const PHINode *PN) {
BinaryOperator *BO = nullptr; BinaryOperator *BO = nullptr;
Value *Start = nullptr, *Step = nullptr; Value *Start = nullptr, *Step = nullptr;
@ -2225,10 +2225,13 @@ static bool isNonZeroRecurrence(const PHINode *PN) {
switch (BO->getOpcode()) { switch (BO->getOpcode()) {
case Instruction::Add: 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)) && return match(Step, m_APInt(StepC)) &&
((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) || ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) ||
(BO->hasNoSignedWrap() && StartC->isStrictlyPositive() && (BO->hasNoSignedWrap() &&
StepC->isNonNegative())); StartC->isNegative() == StepC->isNegative()));
case Instruction::Mul: case Instruction::Mul:
return match(Step, m_APInt(StepC)) && return match(Step, m_APInt(StepC)) &&
((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) || ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) ||

View File

@ -1191,7 +1191,7 @@ TEST_F(ValueTrackingTest, isNonZeroRecurrence) {
)"); )");
DataLayout DL = M->getDataLayout(); DataLayout DL = M->getDataLayout();
AssumptionCache AC(*F); AssumptionCache AC(*F);
EXPECT_FALSE(isKnownNonZero(A, DL, 0, &AC, CxtI)); EXPECT_TRUE(isKnownNonZero(A, DL, 0, &AC, CxtI));
} }
TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) { TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) {