@@ -3334,6 +3334,37 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
3334
3334
return nullptr ;
3335
3335
}
3336
3336
3337
+ // Replaces (switch (select cond, X, C)/(select cond, C, X)) with (switch X) if
3338
+ // we can prove that both (switch C) and (switch X) go to the default when cond
3339
+ // is false/true.
3340
+ static Value *simplifySwitchOnSelectUsingRanges (SwitchInst &SI,
3341
+ SelectInst *Select,
3342
+ unsigned CstOpIdx) {
3343
+ auto *C = dyn_cast<ConstantInt>(Select->getOperand (CstOpIdx));
3344
+ if (!C)
3345
+ return nullptr ;
3346
+
3347
+ BasicBlock *CstBB = SI.findCaseValue (C)->getCaseSuccessor ();
3348
+ if (CstBB != SI.getDefaultDest ())
3349
+ return nullptr ;
3350
+ Value *X = Select->getOperand (3 - CstOpIdx);
3351
+ ICmpInst::Predicate Pred;
3352
+ const APInt *RHSC;
3353
+ if (!match (Select->getCondition (),
3354
+ m_ICmp (Pred, m_Specific (X), m_APInt (RHSC))))
3355
+ return nullptr ;
3356
+ if (CstOpIdx == 1 )
3357
+ Pred = ICmpInst::getInversePredicate (Pred);
3358
+
3359
+ // See whether we can replace the select with X
3360
+ ConstantRange CR = ConstantRange::makeExactICmpRegion (Pred, *RHSC);
3361
+ for (auto Case : SI.cases ())
3362
+ if (!CR.contains (Case.getCaseValue ()->getValue ()))
3363
+ return nullptr ;
3364
+
3365
+ return X;
3366
+ }
3367
+
3337
3368
Instruction *InstCombinerImpl::visitSwitchInst (SwitchInst &SI) {
3338
3369
Value *Cond = SI.getCondition ();
3339
3370
Value *Op0;
@@ -3407,6 +3438,16 @@ Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
3407
3438
}
3408
3439
}
3409
3440
3441
+ // Fold switch(select cond, X, Y) into switch(X/Y) if possible
3442
+ if (auto *Select = dyn_cast<SelectInst>(Cond)) {
3443
+ if (Value *V =
3444
+ simplifySwitchOnSelectUsingRanges (SI, Select, /* CstOpIdx=*/ 1 ))
3445
+ return replaceOperand (SI, 0 , V);
3446
+ if (Value *V =
3447
+ simplifySwitchOnSelectUsingRanges (SI, Select, /* CstOpIdx=*/ 2 ))
3448
+ return replaceOperand (SI, 0 , V);
3449
+ }
3450
+
3410
3451
KnownBits Known = computeKnownBits (Cond, 0 , &SI);
3411
3452
unsigned LeadingKnownZeros = Known.countMinLeadingZeros ();
3412
3453
unsigned LeadingKnownOnes = Known.countMinLeadingOnes ();
0 commit comments