[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;
}
/// 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()) ||

View File

@ -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) {