@@ -782,25 +782,24 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
782
782
783
783
// Match unsigned saturated add of 2 variables with an unnecessary 'not'.
784
784
// There are 8 commuted variants.
785
- // Canonicalize -1 (saturated result) to true value of the select. Just
786
- // swapping the compare operands is legal, because the selected value is the
787
- // same in case of equality, so we can interchange u< and u<=.
785
+ // Canonicalize -1 (saturated result) to true value of the select.
788
786
if (match (FVal, m_AllOnes ())) {
789
787
std::swap (TVal, FVal);
790
- std::swap (Cmp0, Cmp1 );
788
+ Pred = CmpInst::getInversePredicate (Pred );
791
789
}
792
790
if (!match (TVal, m_AllOnes ()))
793
791
return nullptr ;
794
792
795
- // Canonicalize predicate to 'ULT'.
796
- if (Pred == ICmpInst::ICMP_UGT) {
797
- Pred = ICmpInst::ICMP_ULT;
793
+ // Canonicalize predicate to less-than or less-or-equal-than.
794
+ if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) {
798
795
std::swap (Cmp0, Cmp1);
796
+ Pred = CmpInst::getSwappedPredicate (Pred);
799
797
}
800
- if (Pred != ICmpInst::ICMP_ULT)
798
+ if (Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_ULE )
801
799
return nullptr ;
802
800
803
801
// Match unsigned saturated add of 2 variables with an unnecessary 'not'.
802
+ // Strictness of the comparison is irrelevant.
804
803
Value *Y;
805
804
if (match (Cmp0, m_Not (m_Value (X))) &&
806
805
match (FVal, m_c_Add (m_Specific (X), m_Value (Y))) && Y == Cmp1) {
@@ -809,6 +808,7 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
809
808
return Builder.CreateBinaryIntrinsic (Intrinsic::uadd_sat, X, Y);
810
809
}
811
810
// The 'not' op may be included in the sum but not the compare.
811
+ // Strictness of the comparison is irrelevant.
812
812
X = Cmp0;
813
813
Y = Cmp1;
814
814
if (match (FVal, m_c_Add (m_Not (m_Specific (X)), m_Specific (Y)))) {
@@ -819,7 +819,9 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
819
819
Intrinsic::uadd_sat, BO->getOperand (0 ), BO->getOperand (1 ));
820
820
}
821
821
// The overflow may be detected via the add wrapping round.
822
- if (match (Cmp0, m_c_Add (m_Specific (Cmp1), m_Value (Y))) &&
822
+ // This is only valid for strict comparison!
823
+ if (Pred == ICmpInst::ICMP_ULT &&
824
+ match (Cmp0, m_c_Add (m_Specific (Cmp1), m_Value (Y))) &&
823
825
match (FVal, m_c_Add (m_Specific (Cmp1), m_Specific (Y)))) {
824
826
// ((X + Y) u< X) ? -1 : (X + Y) --> uadd.sat(X, Y)
825
827
// ((X + Y) u< Y) ? -1 : (X + Y) --> uadd.sat(X, Y)
0 commit comments