@@ -119,7 +119,7 @@ static Instruction *foldSelectBinOpIdentity(SelectInst &Sel,
119
119
// / (shl (and (X, C1)), (log2(TC-FC) - log2(C1))) + FC
120
120
// / With some variations depending if FC is larger than TC, or the shift
121
121
// / isn't needed, or the bit widths don't match.
122
- static Value *foldSelectICmpAnd (SelectInst &Sel, ICmpInst *Cmp ,
122
+ static Value *foldSelectICmpAnd (SelectInst &Sel, Value *CondVal ,
123
123
InstCombiner::BuilderTy &Builder) {
124
124
const APInt *SelTC, *SelFC;
125
125
if (!match (Sel.getTrueValue (), m_APInt (SelTC)) ||
@@ -128,33 +128,42 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
128
128
129
129
// If this is a vector select, we need a vector compare.
130
130
Type *SelType = Sel.getType ();
131
- if (SelType->isVectorTy () != Cmp ->getType ()->isVectorTy ())
131
+ if (SelType->isVectorTy () != CondVal ->getType ()->isVectorTy ())
132
132
return nullptr ;
133
133
134
134
Value *V;
135
135
APInt AndMask;
136
136
bool CreateAnd = false ;
137
- ICmpInst::Predicate Pred = Cmp->getPredicate ();
138
- if (ICmpInst::isEquality (Pred)) {
139
- if (!match (Cmp->getOperand (1 ), m_Zero ()))
140
- return nullptr ;
137
+ CmpPredicate Pred;
138
+ Value *CmpLHS, *CmpRHS;
141
139
142
- V = Cmp-> getOperand ( 0 );
143
- const APInt *AndRHS;
144
- if (!match (V, m_And ( m_Value (), m_Power2 (AndRHS) )))
145
- return nullptr ;
140
+ if ( match (CondVal, m_ICmp (Pred, m_Value (CmpLHS), m_Value (CmpRHS)))) {
141
+ if ( ICmpInst::isEquality (Pred)) {
142
+ if (!match (CmpRHS, m_Zero ( )))
143
+ return nullptr ;
146
144
147
- AndMask = *AndRHS;
148
- } else if (auto Res = decomposeBitTestICmp (Cmp->getOperand (0 ),
149
- Cmp->getOperand (1 ), Pred)) {
150
- assert (ICmpInst::isEquality (Res->Pred ) && " Not equality test?" );
151
- if (!Res->Mask .isPowerOf2 ())
152
- return nullptr ;
145
+ V = CmpLHS;
146
+ const APInt *AndRHS;
147
+ if (!match (V, m_And (m_Value (), m_Power2 (AndRHS))))
148
+ return nullptr ;
149
+
150
+ AndMask = *AndRHS;
151
+ } else {
152
+ auto Res = decomposeBitTestICmp (CmpLHS, CmpRHS, Pred);
153
+ if (!Res || !Res->Mask .isPowerOf2 ())
154
+ return nullptr ;
155
+ assert (ICmpInst::isEquality (Res->Pred ) && " Not equality test?" );
153
156
154
- V = Res->X ;
155
- AndMask = Res->Mask ;
156
- Pred = Res->Pred ;
157
- CreateAnd = true ;
157
+ V = Res->X ;
158
+ AndMask = Res->Mask ;
159
+ Pred = Res->Pred ;
160
+ CreateAnd = true ;
161
+ }
162
+ } else if (auto *Trunc = dyn_cast<TruncInst>(CondVal)) {
163
+ V = Trunc->getOperand (0 );
164
+ AndMask = APInt (V->getType ()->getScalarSizeInBits (), 1 );
165
+ Pred = ICmpInst::ICMP_NE;
166
+ CreateAnd = !Trunc->hasNoUnsignedWrap ();
158
167
} else {
159
168
return nullptr ;
160
169
}
@@ -172,7 +181,7 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
172
181
return nullptr ;
173
182
// If we have to create an 'and', then we must kill the cmp to not
174
183
// increase the instruction count.
175
- if (CreateAnd && !Cmp ->hasOneUse ())
184
+ if (CreateAnd && !CondVal ->hasOneUse ())
176
185
return nullptr ;
177
186
178
187
// (V & AndMaskC) == 0 ? TC : FC --> TC | (V & AndMaskC)
@@ -213,7 +222,7 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
213
222
// a 'select' + 'icmp', then this transformation would result in more
214
223
// instructions and potentially interfere with other folding.
215
224
if (CreateAnd + ShouldNotVal + NeedShift + NeedZExtTrunc >
216
- 1 + Cmp ->hasOneUse ())
225
+ 1 + CondVal ->hasOneUse ())
217
226
return nullptr ;
218
227
219
228
// Insert the 'and' instruction on the input to the truncate.
@@ -1955,9 +1964,6 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
1955
1964
tryToReuseConstantFromSelectInComparison (SI, *ICI, *this ))
1956
1965
return NewSel;
1957
1966
1958
- if (Value *V = foldSelectICmpAnd (SI, ICI, Builder))
1959
- return replaceInstUsesWith (SI, V);
1960
-
1961
1967
// NOTE: if we wanted to, this is where to detect integer MIN/MAX
1962
1968
bool Changed = false ;
1963
1969
Value *TrueVal = SI.getTrueValue ();
@@ -3955,6 +3961,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
3955
3961
if (Instruction *Result = foldSelectInstWithICmp (SI, ICI))
3956
3962
return Result;
3957
3963
3964
+ if (Value *V = foldSelectICmpAnd (SI, CondVal, Builder))
3965
+ return replaceInstUsesWith (SI, V);
3966
+
3958
3967
if (Value *V = foldSelectICmpAndBinOp (CondVal, TrueVal, FalseVal, Builder))
3959
3968
return replaceInstUsesWith (SI, V);
3960
3969
0 commit comments