@@ -2471,6 +2471,34 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
2471
2471
return ::isKnownNonEqual (X, Y, Depth, Q);
2472
2472
}
2473
2473
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
+
2474
2502
static bool isNonZeroShift (const Operator *I, const APInt &DemandedElts,
2475
2503
unsigned Depth, const SimplifyQuery &Q,
2476
2504
const KnownBits &KnownVal) {
@@ -2666,33 +2694,10 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
2666
2694
Q.IIQ .hasNoUnsignedWrap (BO));
2667
2695
}
2668
2696
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.
2671
2697
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));
2696
2701
}
2697
2702
case Instruction::Select: {
2698
2703
// (C ? X : Y) != 0 if X != 0 and Y != 0.
0 commit comments