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 @@ -2769,6 +2769,17 @@ // 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) { + KnownBits XKnown = + computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q); + KnownBits YKnown = + computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q); + std::optional YUleX = KnownBits::ule(YKnown, XKnown); + + // If Y u<= X then div is only zero if X is zero. + if (YUleX && *YUleX) + return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q); + } 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 @@ -501,12 +501,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