diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 54539d2..06162c6 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2570,26 +2570,33 @@ static bool isKnownNonZeroFromOperator(const Operator *I, return isNonZeroShift(I, DemandedElts, Depth, Q, Known); } case Instruction::UDiv: - case Instruction::SDiv: + case Instruction::SDiv: { // X / Y // div exact can only produce a zero if the dividend is zero. if (cast<PossiblyExactOperator>(I)->isExact()) return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q); - if (I->getOpcode() == Instruction::UDiv) { - std::optional<bool> XUgeY; - KnownBits XKnown = - computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q); - if (!XKnown.isUnknown()) { - KnownBits YKnown = - computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q); - // If X u>= Y then div is non zero (0/0 is UB). - XUgeY = KnownBits::uge(XKnown, YKnown); - } - // If X is total unknown or X u< Y we won't be able to prove non-zero - // with compute known bits so just return early. - return XUgeY && *XUgeY; + + std::optional<bool> XUgeY; + KnownBits XKnown = + computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q); + // If X is fully unknown we won't be able to figure anything out so don't + // both computing knownbits for Y. + if (XKnown.isUnknown()) + return false; + + KnownBits YKnown = + computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q); + if (I->getOpcode() == Instruction::SDiv) { + // For signed division need to compare abs value of the operands. + XKnown = XKnown.abs(/*IntMinIsPoison*/ false); + YKnown = YKnown.abs(/*IntMinIsPoison*/ false); } - break; + // If X u>= Y then div is non zero (0/0 is UB). + XUgeY = KnownBits::uge(XKnown, YKnown); + // If X is total unknown or X u< Y we won't be able to prove non-zero + // with compute known bits so just return early. + return XUgeY && *XUgeY; + } case Instruction::Add: { // X + Y. |