Skip to content

Commit 42e25fe

Browse files
committed
[ValueTracking] Split isNonZero(mul) logic to a helper; NFC
1 parent 2d1b21d commit 42e25fe

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

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

0 commit comments

Comments
 (0)