@@ -2464,6 +2464,34 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
2464
2464
return ::isKnownNonEqual (X, Y, Depth, Q);
2465
2465
}
2466
2466
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
+
2467
2495
static bool isNonZeroShift (const Operator *I, const APInt &DemandedElts,
2468
2496
unsigned Depth, const SimplifyQuery &Q,
2469
2497
const KnownBits &KnownVal) {
@@ -2659,33 +2687,10 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
2659
2687
Q.IIQ .hasNoUnsignedWrap (BO));
2660
2688
}
2661
2689
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.
2664
2690
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));
2689
2694
}
2690
2695
case Instruction::Select: {
2691
2696
// (C ? X : Y) != 0 if X != 0 and Y != 0.
0 commit comments