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