@@ -3031,7 +3031,9 @@ enum class MonotonicType { GreaterEq, LowerEq };
30313031
30323032// / Get values V_i such that V uge V_i (GreaterEq) or V ule V_i (LowerEq).
30333033static void getUnsignedMonotonicValues (SmallPtrSetImpl<Value *> &Res, Value *V,
3034- MonotonicType Type, unsigned Depth = 0 ) {
3034+ MonotonicType Type,
3035+ const SimplifyQuery &Q,
3036+ unsigned Depth = 0 ) {
30353037 if (!Res.insert (V).second )
30363038 return ;
30373039
@@ -3047,24 +3049,31 @@ static void getUnsignedMonotonicValues(SmallPtrSetImpl<Value *> &Res, Value *V,
30473049 if (Type == MonotonicType::GreaterEq) {
30483050 if (match (I, m_Or (m_Value (X), m_Value (Y))) ||
30493051 match (I, m_Intrinsic<Intrinsic::uadd_sat>(m_Value (X), m_Value (Y)))) {
3050- getUnsignedMonotonicValues (Res, X, Type, Depth);
3051- getUnsignedMonotonicValues (Res, Y, Type, Depth);
3052+ getUnsignedMonotonicValues (Res, X, Type, Q, Depth);
3053+ getUnsignedMonotonicValues (Res, Y, Type, Q, Depth);
3054+ }
3055+ // X * Y >= X --> true
3056+ if (match (I, m_NUWMul (m_Value (X), m_Value (Y)))) {
3057+ if (isKnownNonZero (X, Q))
3058+ getUnsignedMonotonicValues (Res, Y, Type, Q, Depth);
3059+ if (isKnownNonZero (Y, Q))
3060+ getUnsignedMonotonicValues (Res, X, Type, Q, Depth);
30523061 }
30533062 } else {
30543063 assert (Type == MonotonicType::LowerEq);
30553064 switch (I->getOpcode ()) {
30563065 case Instruction::And:
3057- getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Depth);
3058- getUnsignedMonotonicValues (Res, I->getOperand (1 ), Type, Depth);
3066+ getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Q, Depth);
3067+ getUnsignedMonotonicValues (Res, I->getOperand (1 ), Type, Q, Depth);
30593068 break ;
30603069 case Instruction::URem:
30613070 case Instruction::UDiv:
30623071 case Instruction::LShr:
3063- getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Depth);
3072+ getUnsignedMonotonicValues (Res, I->getOperand (0 ), Type, Q, Depth);
30643073 break ;
30653074 case Instruction::Call:
30663075 if (match (I, m_Intrinsic<Intrinsic::usub_sat>(m_Value (X))))
3067- getUnsignedMonotonicValues (Res, X, Type, Depth);
3076+ getUnsignedMonotonicValues (Res, X, Type, Q, Depth);
30683077 break ;
30693078 default :
30703079 break ;
@@ -3073,16 +3082,16 @@ static void getUnsignedMonotonicValues(SmallPtrSetImpl<Value *> &Res, Value *V,
30733082}
30743083
30753084static Value *simplifyICmpUsingMonotonicValues (CmpPredicate Pred, Value *LHS,
3076- Value *RHS) {
3085+ Value *RHS,
3086+ const SimplifyQuery &Q) {
30773087 if (Pred != ICmpInst::ICMP_UGE && Pred != ICmpInst::ICMP_ULT)
30783088 return nullptr ;
3079-
30803089 // We have LHS uge GreaterValues and LowerValues uge RHS. If any of the
30813090 // GreaterValues and LowerValues are the same, it follows that LHS uge RHS.
30823091 SmallPtrSet<Value *, 4 > GreaterValues;
30833092 SmallPtrSet<Value *, 4 > LowerValues;
3084- getUnsignedMonotonicValues (GreaterValues, LHS, MonotonicType::GreaterEq);
3085- getUnsignedMonotonicValues (LowerValues, RHS, MonotonicType::LowerEq);
3093+ getUnsignedMonotonicValues (GreaterValues, LHS, MonotonicType::GreaterEq, Q );
3094+ getUnsignedMonotonicValues (LowerValues, RHS, MonotonicType::LowerEq, Q );
30863095 for (Value *GV : GreaterValues)
30873096 if (LowerValues.contains (GV))
30883097 return ConstantInt::getBool (getCompareTy (LHS),
@@ -3994,14 +4003,16 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
39944003
39954004 if (Value *V = simplifyICmpWithIntrinsicOnLHS (Pred, LHS, RHS))
39964005 return V;
4006+
39974007 if (Value *V = simplifyICmpWithIntrinsicOnLHS (
39984008 ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
39994009 return V;
40004010
4001- if (Value *V = simplifyICmpUsingMonotonicValues (Pred, LHS, RHS))
4011+ if (Value *V = simplifyICmpUsingMonotonicValues (Pred, LHS, RHS, Q ))
40024012 return V;
4013+
40034014 if (Value *V = simplifyICmpUsingMonotonicValues (
4004- ICmpInst::getSwappedPredicate (Pred), RHS, LHS))
4015+ ICmpInst::getSwappedPredicate (Pred), RHS, LHS, Q ))
40054016 return V;
40064017
40074018 if (Value *V = simplifyICmpWithDominatingAssume (Pred, LHS, RHS, Q))
0 commit comments