Skip to content

Commit e5d45a5

Browse files
committed
[ValueTracking] Split isNonZero(mul) logic to a helper; NFC
1 parent 4ac637d commit e5d45a5

File tree

1 file changed

+31
-26
lines changed

1 file changed

+31
-26
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,6 +2463,34 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
24632463
return ::isKnownNonEqual(X, Y, Depth, Q);
24642464
}
24652465

2466+
static bool isNonZeroMul(const APInt &DemandedElts, unsigned Depth,
2467+
const SimplifyQuery &Q, unsigned BitWidth, Value *X,
2468+
Value *Y, bool NSW, bool NUW) {
2469+
// If X and Y are non-zero then so is X * Y as long as the multiplication
2470+
// does not overflow.
2471+
if (NSW || NUW)
2472+
return isKnownNonZero(X, DemandedElts, Depth, Q) &&
2473+
isKnownNonZero(Y, DemandedElts, Depth, Q);
2474+
2475+
// If either X or Y is odd, then if the other is non-zero the result can't
2476+
// be zero.
2477+
KnownBits XKnown = computeKnownBits(X, DemandedElts, Depth, Q);
2478+
if (XKnown.One[0])
2479+
return isKnownNonZero(Y, DemandedElts, Depth, Q);
2480+
2481+
KnownBits YKnown = computeKnownBits(Y, DemandedElts, Depth, Q);
2482+
if (YKnown.One[0])
2483+
return XKnown.isNonZero() || isKnownNonZero(X, DemandedElts, Depth, Q);
2484+
2485+
// If there exists any subset of X (sX) and subset of Y (sY) s.t sX * sY is
2486+
// non-zero, then X * Y is non-zero. We can find sX and sY by just taking
2487+
// the lowest known One of X and Y. If they are non-zero, the result
2488+
// must be non-zero. We can check if LSB(X) * LSB(Y) != 0 by doing
2489+
// X.CountLeadingZeros + Y.CountLeadingZeros < BitWidth.
2490+
return (XKnown.countMaxTrailingZeros() + YKnown.countMaxTrailingZeros()) <
2491+
BitWidth;
2492+
}
2493+
24662494
static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
24672495
unsigned Depth, const SimplifyQuery &Q,
24682496
const KnownBits &KnownVal) {
@@ -2658,33 +2686,10 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
26582686
Q.IIQ.hasNoUnsignedWrap(BO));
26592687
}
26602688
case Instruction::Mul: {
2661-
// If X and Y are non-zero then so is X * Y as long as the multiplication
2662-
// does not overflow.
26632689
const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
2664-
if (Q.IIQ.hasNoSignedWrap(BO) || Q.IIQ.hasNoUnsignedWrap(BO))
2665-
return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) &&
2666-
isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q);
2667-
2668-
// If either X or Y is odd, then if the other is non-zero the result can't
2669-
// be zero.
2670-
KnownBits XKnown =
2671-
computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q);
2672-
if (XKnown.One[0])
2673-
return isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q);
2674-
2675-
KnownBits YKnown =
2676-
computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q);
2677-
if (YKnown.One[0])
2678-
return XKnown.isNonZero() ||
2679-
isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q);
2680-
2681-
// If there exists any subset of X (sX) and subset of Y (sY) s.t sX * sY is
2682-
// non-zero, then X * Y is non-zero. We can find sX and sY by just taking
2683-
// the lowest known One of X and Y. If they are non-zero, the result
2684-
// must be non-zero. We can check if LSB(X) * LSB(Y) != 0 by doing
2685-
// X.CountLeadingZeros + Y.CountLeadingZeros < BitWidth.
2686-
return (XKnown.countMaxTrailingZeros() + YKnown.countMaxTrailingZeros()) <
2687-
BitWidth;
2690+
return isNonZeroMul(DemandedElts, Depth, Q, BitWidth, I->getOperand(0),
2691+
I->getOperand(1), Q.IIQ.hasNoSignedWrap(BO),
2692+
Q.IIQ.hasNoUnsignedWrap(BO));
26882693
}
26892694
case Instruction::Select: {
26902695
// (C ? X : Y) != 0 if X != 0 and Y != 0.

0 commit comments

Comments
 (0)