diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 85361e5f54d76..696c14607466c 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2512,6 +2512,24 @@ static bool isNonZeroRecurrence(const PHINode *PN) { } } +static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth, + const Query &Q, unsigned BitWidth, Value *X, + Value *Y) { + if (auto *C = dyn_cast(X)) + if (C->isNullValue() && isKnownNonZero(Y, DemandedElts, Depth, Q)) + return true; + + KnownBits XKnown = computeKnownBits(X, DemandedElts, Depth, Q); + if (XKnown.isUnknown()) + return false; + KnownBits YKnown = computeKnownBits(Y, DemandedElts, Depth, Q); + // If X != Y then X - Y is non zero. + std::optional ne = KnownBits::ne(XKnown, YKnown); + // If we are unable to compute if X != Y, we won't be able to do anything + // computing the knownbits of the sub expression so just return here. + return ne && *ne; +} + static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts, unsigned Depth, const Query &Q, const KnownBits &KnownVal) { @@ -2705,25 +2723,9 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, Q.DL.getTypeSizeInBits(I->getType()).getFixedValue()) return isKnownNonZero(I->getOperand(0), Depth, Q); break; - case Instruction::Sub: { - if (auto *C = dyn_cast(I->getOperand(0))) - if (C->isNullValue() && - isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q)) - return true; - - KnownBits XKnown = - computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q); - if (!XKnown.isUnknown()) { - KnownBits YKnown = - computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q); - // If X != Y then X - Y is non zero. - std::optional ne = KnownBits::ne(XKnown, YKnown); - // If we are unable to compute if X != Y, we won't be able to do anything - // computing the knownbits of the sub expression so just return here. - return ne && *ne; - } - return false; - } + case Instruction::Sub: + return isNonZeroSub(DemandedElts, Depth, Q, BitWidth, I->getOperand(0), + I->getOperand(1)); case Instruction::Or: // X | Y != 0 if X != 0 or Y != 0. return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) ||