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