Skip to content

Commit f0a487d

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

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
@@ -2471,6 +2471,34 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
24712471
return ::isKnownNonEqual(X, Y, Depth, Q);
24722472
}
24732473

2474+
static bool isNonZeroMul(const APInt &DemandedElts, unsigned Depth,
2475+
const SimplifyQuery &Q, unsigned BitWidth, Value *X,
2476+
Value *Y, bool NSW, bool NUW) {
2477+
// If X and Y are non-zero then so is X * Y as long as the multiplication
2478+
// does not overflow.
2479+
if (NSW || NUW)
2480+
return isKnownNonZero(X, DemandedElts, Depth, Q) &&
2481+
isKnownNonZero(Y, DemandedElts, Depth, Q);
2482+
2483+
// If either X or Y is odd, then if the other is non-zero the result can't
2484+
// be zero.
2485+
KnownBits XKnown = computeKnownBits(X, DemandedElts, Depth, Q);
2486+
if (XKnown.One[0])
2487+
return isKnownNonZero(Y, DemandedElts, Depth, Q);
2488+
2489+
KnownBits YKnown = computeKnownBits(Y, DemandedElts, Depth, Q);
2490+
if (YKnown.One[0])
2491+
return XKnown.isNonZero() || isKnownNonZero(X, DemandedElts, Depth, Q);
2492+
2493+
// If there exists any subset of X (sX) and subset of Y (sY) s.t sX * sY is
2494+
// non-zero, then X * Y is non-zero. We can find sX and sY by just taking
2495+
// the lowest known One of X and Y. If they are non-zero, the result
2496+
// must be non-zero. We can check if LSB(X) * LSB(Y) != 0 by doing
2497+
// X.CountLeadingZeros + Y.CountLeadingZeros < BitWidth.
2498+
return (XKnown.countMaxTrailingZeros() + YKnown.countMaxTrailingZeros()) <
2499+
BitWidth;
2500+
}
2501+
24742502
static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
24752503
unsigned Depth, const SimplifyQuery &Q,
24762504
const KnownBits &KnownVal) {
@@ -2666,33 +2694,10 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
26662694
Q.IIQ.hasNoUnsignedWrap(BO));
26672695
}
26682696
case Instruction::Mul: {
2669-
// If X and Y are non-zero then so is X * Y as long as the multiplication
2670-
// does not overflow.
26712697
const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
2672-
if (Q.IIQ.hasNoSignedWrap(BO) || Q.IIQ.hasNoUnsignedWrap(BO))
2673-
return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) &&
2674-
isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q);
2675-
2676-
// If either X or Y is odd, then if the other is non-zero the result can't
2677-
// be zero.
2678-
KnownBits XKnown =
2679-
computeKnownBits(I->getOperand(0), DemandedElts, Depth, Q);
2680-
if (XKnown.One[0])
2681-
return isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q);
2682-
2683-
KnownBits YKnown =
2684-
computeKnownBits(I->getOperand(1), DemandedElts, Depth, Q);
2685-
if (YKnown.One[0])
2686-
return XKnown.isNonZero() ||
2687-
isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q);
2688-
2689-
// If there exists any subset of X (sX) and subset of Y (sY) s.t sX * sY is
2690-
// non-zero, then X * Y is non-zero. We can find sX and sY by just taking
2691-
// the lowest known One of X and Y. If they are non-zero, the result
2692-
// must be non-zero. We can check if LSB(X) * LSB(Y) != 0 by doing
2693-
// X.CountLeadingZeros + Y.CountLeadingZeros < BitWidth.
2694-
return (XKnown.countMaxTrailingZeros() + YKnown.countMaxTrailingZeros()) <
2695-
BitWidth;
2698+
return isNonZeroMul(DemandedElts, Depth, Q, BitWidth, I->getOperand(0),
2699+
I->getOperand(1), Q.IIQ.hasNoSignedWrap(BO),
2700+
Q.IIQ.hasNoUnsignedWrap(BO));
26962701
}
26972702
case Instruction::Select: {
26982703
// (C ? X : Y) != 0 if X != 0 and Y != 0.

0 commit comments

Comments
 (0)