@@ -2872,11 +2872,24 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
2872
2872
// If X and Y are non-zero then so is X * Y as long as the multiplication
2873
2873
// does not overflow.
2874
2874
const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(V);
2875
- if ((Q.IIQ .hasNoSignedWrap (BO) || Q.IIQ .hasNoUnsignedWrap (BO)) &&
2876
- isKnownNonZero (I->getOperand (0 ), DemandedElts, Depth, Q) &&
2877
- isKnownNonZero (I->getOperand (1 ), DemandedElts, Depth, Q))
2878
- return true ;
2879
- break ;
2875
+ if (Q.IIQ .hasNoSignedWrap (BO) || Q.IIQ .hasNoUnsignedWrap (BO))
2876
+ return isKnownNonZero (I->getOperand (0 ), DemandedElts, Depth, Q) &&
2877
+ isKnownNonZero (I->getOperand (1 ), DemandedElts, Depth, Q);
2878
+
2879
+ // If either X or Y is odd, then if the other is non-zero the result can't
2880
+ // be zero.
2881
+ KnownBits XKnown =
2882
+ computeKnownBits (I->getOperand (0 ), DemandedElts, Depth, Q);
2883
+ if (XKnown.One [0 ])
2884
+ return isKnownNonZero (I->getOperand (1 ), DemandedElts, Depth, Q);
2885
+
2886
+ KnownBits YKnown =
2887
+ computeKnownBits (I->getOperand (1 ), DemandedElts, Depth, Q);
2888
+ if (YKnown.One [0 ])
2889
+ return XKnown.isNonZero () ||
2890
+ isKnownNonZero (I->getOperand (0 ), DemandedElts, Depth, Q);
2891
+
2892
+ return KnownBits::mul (XKnown, YKnown).isNonZero ();
2880
2893
}
2881
2894
case Instruction::Select:
2882
2895
// (C ? X : Y) != 0 if X != 0 and Y != 0.
0 commit comments