diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2766,9 +2766,24 @@ } case Instruction::UDiv: case Instruction::SDiv: + // X / Y // div exact can only produce a zero if the dividend is zero. if (cast(I)->isExact()) return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q); + if (I->getOpcode() == Instruction::UDiv) { + std::optional 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; + } break; case Instruction::Add: { // X + Y. diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -499,12 +499,7 @@ define i1 @udiv_y_le_x(i8 %xx, i8 %yy, i8 %z) { ; CHECK-LABEL: @udiv_y_le_x( -; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 7 -; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], 7 -; CHECK-NEXT: [[D:%.*]] = udiv i8 [[X]], [[Y]] -; CHECK-NEXT: [[O:%.*]] = or i8 [[D]], [[Z:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[O]], 0 -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %x = or i8 %xx, 7 %y = and i8 %yy, 7