@@ -6198,7 +6198,7 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
6198
6198
// TODO: Handle switches with more than 2 cases that map to the same result.
6199
6199
static Value *foldSwitchToSelect (const SwitchCaseResultVectorTy &ResultVector,
6200
6200
Constant *DefaultResult, Value *Condition,
6201
- IRBuilder<> &Builder) {
6201
+ IRBuilder<> &Builder, const DataLayout &DL ) {
6202
6202
// If we are selecting between only two cases transform into a simple
6203
6203
// select or a two-way select if default is possible.
6204
6204
// Example:
@@ -6234,10 +6234,33 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
6234
6234
// case 0,2,8,10 -> Cond & 0b1..0101 == 0 ? result : default
6235
6235
if (isPowerOf2_32 (CaseCount)) {
6236
6236
ConstantInt *MinCaseVal = CaseValues[0 ];
6237
- // Find mininal value.
6238
- for (auto *Case : CaseValues)
6237
+ // If there are bits that are set exclusively by CaseValues, we
6238
+ // can transform the switch into a select if the conjunction of
6239
+ // all the values uniquely identify CaseValues.
6240
+ APInt AndMask = APInt::getAllOnes (MinCaseVal->getBitWidth ());
6241
+
6242
+ // Find the minimum value and compute the and of all the case values.
6243
+ for (auto *Case : CaseValues) {
6239
6244
if (Case->getValue ().slt (MinCaseVal->getValue ()))
6240
6245
MinCaseVal = Case;
6246
+ AndMask &= Case->getValue ();
6247
+ }
6248
+ KnownBits Known = computeKnownBits (Condition, DL);
6249
+
6250
+ if (!AndMask.isZero () && Known.getMaxValue ().uge (AndMask)) {
6251
+ // Compute the number of bits that are free to vary.
6252
+ unsigned FreeBits = Known.countMaxActiveBits () - AndMask.popcount ();
6253
+
6254
+ // Check if the number of values covered by the mask is equal
6255
+ // to the number of cases.
6256
+ if (FreeBits == Log2_32 (CaseCount)) {
6257
+ Value *And = Builder.CreateAnd (Condition, AndMask);
6258
+ Value *Cmp = Builder.CreateICmpEQ (
6259
+ And, Constant::getIntegerValue (And->getType (), AndMask));
6260
+ return Builder.CreateSelect (Cmp, ResultVector[0 ].first ,
6261
+ DefaultResult);
6262
+ }
6263
+ }
6241
6264
6242
6265
// Mark the bits case number touched.
6243
6266
APInt BitMask = APInt::getZero (MinCaseVal->getBitWidth ());
@@ -6325,7 +6348,7 @@ static bool trySwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
6325
6348
assert (PHI != nullptr && " PHI for value select not found" );
6326
6349
Builder.SetInsertPoint (SI);
6327
6350
Value *SelectValue =
6328
- foldSwitchToSelect (UniqueResults, DefaultResult, Cond, Builder);
6351
+ foldSwitchToSelect (UniqueResults, DefaultResult, Cond, Builder, DL );
6329
6352
if (!SelectValue)
6330
6353
return false ;
6331
6354
0 commit comments