From d8e9dd33b2a5546af0b26243810712629d4d5f14 Mon Sep 17 00:00:00 2001 From: Noah Goldstein Date: Thu, 27 Apr 2023 11:03:40 -0500 Subject: [PATCH] [ValueTracking] Add logic for `udiv x,y != 0` if `y u<= x` Alive2 Link: https://alive2.llvm.org/ce/z/2DKh46 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D149203 --- llvm/lib/Analysis/ValueTracking.cpp | 15 +++++++++++++++ llvm/test/Analysis/ValueTracking/known-non-zero.ll | 7 +------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 028920c..c36bb35 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2766,9 +2766,24 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, } 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 index d913c6b..e3470bb 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -499,12 +499,7 @@ define i1 @add_nonzero_nsw_fail(i8 %x, i8 %y) { 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 -- 2.7.4