@@ -5614,14 +5614,29 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
56145614 return true ;
56155615 break ;
56165616 }
5617- case ISD::UDIV:
5618- case ISD::SDIV:
5617+ case ISD::UDIV: {
56195618 // div exact can only produce a zero if the dividend is zero.
5620- // TODO: For udiv this is also true if Op1 u<= Op0
56215619 if (Op->getFlags ().hasExact ())
56225620 return isKnownNeverZero (Op.getOperand (0 ), Depth + 1 );
5623- break ;
56245621
5622+ // If Op0 >= Op1, then the result is at least 1, and therefore not 0.
5623+ KnownBits Op0 = computeKnownBits (Op.getOperand (0 ), Depth + 1 );
5624+ KnownBits Op1 = computeKnownBits (Op.getOperand (1 ), Depth + 1 );
5625+ std::optional<bool > Uge = KnownBits::uge (Op0, Op1);
5626+ return Uge && *Uge;
5627+ }
5628+ case ISD::SDIV: {
5629+ // div exact can only produce a zero if the dividend is zero.
5630+ if (Op->getFlags ().hasExact ())
5631+ return isKnownNeverZero (Op.getOperand (0 ), Depth + 1 );
5632+
5633+ KnownBits Op0 = computeKnownBits (Op.getOperand (0 ), Depth + 1 );
5634+ KnownBits Op1 = computeKnownBits (Op.getOperand (1 ), Depth + 1 );
5635+ Op0 = Op0.abs (/* IntMinIsPoison*/ false );
5636+ Op1 = Op1.abs (/* IntMinIsPoison*/ false );
5637+ std::optional<bool > Uge = KnownBits::uge (Op0, Op1);
5638+ return Uge && *Uge;
5639+ }
56255640 case ISD::ADD:
56265641 if (Op->getFlags ().hasNoUnsignedWrap ())
56275642 if (isKnownNeverZero (Op.getOperand (1 ), Depth + 1 ) ||
0 commit comments