@@ -1065,6 +1065,63 @@ void llvm::adjustKnownBitsForSelectArm(KnownBits &Known, Value *Cond,
1065
1065
Known = CondRes;
1066
1066
}
1067
1067
1068
+ // Match a signed min+max clamp pattern like smax(smin(In, CHigh), CLow).
1069
+ // Returns the input and lower/upper bounds.
1070
+ static bool isSignedMinMaxClamp (const Value *Select, const Value *&In,
1071
+ const APInt *&CLow, const APInt *&CHigh) {
1072
+ assert (isa<Operator>(Select) &&
1073
+ cast<Operator>(Select)->getOpcode () == Instruction::Select &&
1074
+ " Input should be a Select!" );
1075
+
1076
+ const Value *LHS = nullptr , *RHS = nullptr ;
1077
+ SelectPatternFlavor SPF = matchSelectPattern (Select, LHS, RHS).Flavor ;
1078
+ if (SPF != SPF_SMAX && SPF != SPF_SMIN)
1079
+ return false ;
1080
+
1081
+ if (!match (RHS, m_APInt (CLow)))
1082
+ return false ;
1083
+
1084
+ const Value *LHS2 = nullptr , *RHS2 = nullptr ;
1085
+ SelectPatternFlavor SPF2 = matchSelectPattern (LHS, LHS2, RHS2).Flavor ;
1086
+ if (getInverseMinMaxFlavor (SPF) != SPF2)
1087
+ return false ;
1088
+
1089
+ if (!match (RHS2, m_APInt (CHigh)))
1090
+ return false ;
1091
+
1092
+ if (SPF == SPF_SMIN)
1093
+ std::swap (CLow, CHigh);
1094
+
1095
+ In = LHS2;
1096
+ return CLow->sle (*CHigh);
1097
+ }
1098
+
1099
+ static bool isSignedMinMaxIntrinsicClamp (const IntrinsicInst *II,
1100
+ const APInt *&CLow,
1101
+ const APInt *&CHigh) {
1102
+ assert ((II->getIntrinsicID () == Intrinsic::smin ||
1103
+ II->getIntrinsicID () == Intrinsic::smax) &&
1104
+ " Must be smin/smax" );
1105
+
1106
+ Intrinsic::ID InverseID = getInverseMinMaxIntrinsic (II->getIntrinsicID ());
1107
+ auto *InnerII = dyn_cast<IntrinsicInst>(II->getArgOperand (0 ));
1108
+ if (!InnerII || InnerII->getIntrinsicID () != InverseID ||
1109
+ !match (II->getArgOperand (1 ), m_APInt (CLow)) ||
1110
+ !match (InnerII->getArgOperand (1 ), m_APInt (CHigh)))
1111
+ return false ;
1112
+
1113
+ if (II->getIntrinsicID () == Intrinsic::smin)
1114
+ std::swap (CLow, CHigh);
1115
+ return CLow->sle (*CHigh);
1116
+ }
1117
+
1118
+ static void unionWithMinMaxIntrinsicClamp (const IntrinsicInst *II,
1119
+ KnownBits &Known) {
1120
+ const APInt *CLow, *CHigh;
1121
+ if (isSignedMinMaxIntrinsicClamp (II, CLow, CHigh))
1122
+ Known = Known.unionWith (ConstantRange (*CLow, *CHigh + 1 ).toKnownBits ());
1123
+ }
1124
+
1068
1125
static void computeKnownBitsFromOperator (const Operator *I,
1069
1126
const APInt &DemandedElts,
1070
1127
KnownBits &Known, unsigned Depth,
@@ -1804,11 +1861,13 @@ static void computeKnownBitsFromOperator(const Operator *I,
1804
1861
computeKnownBits (I->getOperand (0 ), DemandedElts, Known, Depth + 1 , Q);
1805
1862
computeKnownBits (I->getOperand (1 ), DemandedElts, Known2, Depth + 1 , Q);
1806
1863
Known = KnownBits::smin (Known, Known2);
1864
+ unionWithMinMaxIntrinsicClamp (II, Known);
1807
1865
break ;
1808
1866
case Intrinsic::smax:
1809
1867
computeKnownBits (I->getOperand (0 ), DemandedElts, Known, Depth + 1 , Q);
1810
1868
computeKnownBits (I->getOperand (1 ), DemandedElts, Known2, Depth + 1 , Q);
1811
1869
Known = KnownBits::smax (Known, Known2);
1870
+ unionWithMinMaxIntrinsicClamp (II, Known);
1812
1871
break ;
1813
1872
case Intrinsic::ptrmask: {
1814
1873
computeKnownBits (I->getOperand (0 ), DemandedElts, Known, Depth + 1 , Q);
@@ -3751,55 +3810,6 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
3751
3810
return false ;
3752
3811
}
3753
3812
3754
- // Match a signed min+max clamp pattern like smax(smin(In, CHigh), CLow).
3755
- // Returns the input and lower/upper bounds.
3756
- static bool isSignedMinMaxClamp (const Value *Select, const Value *&In,
3757
- const APInt *&CLow, const APInt *&CHigh) {
3758
- assert (isa<Operator>(Select) &&
3759
- cast<Operator>(Select)->getOpcode () == Instruction::Select &&
3760
- " Input should be a Select!" );
3761
-
3762
- const Value *LHS = nullptr , *RHS = nullptr ;
3763
- SelectPatternFlavor SPF = matchSelectPattern (Select, LHS, RHS).Flavor ;
3764
- if (SPF != SPF_SMAX && SPF != SPF_SMIN)
3765
- return false ;
3766
-
3767
- if (!match (RHS, m_APInt (CLow)))
3768
- return false ;
3769
-
3770
- const Value *LHS2 = nullptr , *RHS2 = nullptr ;
3771
- SelectPatternFlavor SPF2 = matchSelectPattern (LHS, LHS2, RHS2).Flavor ;
3772
- if (getInverseMinMaxFlavor (SPF) != SPF2)
3773
- return false ;
3774
-
3775
- if (!match (RHS2, m_APInt (CHigh)))
3776
- return false ;
3777
-
3778
- if (SPF == SPF_SMIN)
3779
- std::swap (CLow, CHigh);
3780
-
3781
- In = LHS2;
3782
- return CLow->sle (*CHigh);
3783
- }
3784
-
3785
- static bool isSignedMinMaxIntrinsicClamp (const IntrinsicInst *II,
3786
- const APInt *&CLow,
3787
- const APInt *&CHigh) {
3788
- assert ((II->getIntrinsicID () == Intrinsic::smin ||
3789
- II->getIntrinsicID () == Intrinsic::smax) && " Must be smin/smax" );
3790
-
3791
- Intrinsic::ID InverseID = getInverseMinMaxIntrinsic (II->getIntrinsicID ());
3792
- auto *InnerII = dyn_cast<IntrinsicInst>(II->getArgOperand (0 ));
3793
- if (!InnerII || InnerII->getIntrinsicID () != InverseID ||
3794
- !match (II->getArgOperand (1 ), m_APInt (CLow)) ||
3795
- !match (InnerII->getArgOperand (1 ), m_APInt (CHigh)))
3796
- return false ;
3797
-
3798
- if (II->getIntrinsicID () == Intrinsic::smin)
3799
- std::swap (CLow, CHigh);
3800
- return CLow->sle (*CHigh);
3801
- }
3802
-
3803
3813
// / For vector constants, loop over the elements and find the constant with the
3804
3814
// / minimum number of sign bits. Return 0 if the value is not a vector constant
3805
3815
// / or if any element was not analyzed; otherwise, return the count for the
0 commit comments