@@ -7540,6 +7540,62 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
75407540 return true ;
75417541}
75427542
7543+ // / Tries to transform the switch when the condition is umin and a constant.
7544+ // / In that case, the default branch can be replaced by the constant's branch.
7545+ // / For example:
7546+ // / switch(umin(a, 3)) {
7547+ // / case 0:
7548+ // / case 1:
7549+ // / case 2:
7550+ // / case 3:
7551+ // / // ...
7552+ // / default:
7553+ // / unreachable
7554+ // / }
7555+ // /
7556+ // / Transforms into:
7557+ // /
7558+ // / switch(umin(a, 3)) {
7559+ // / case 0:
7560+ // / case 1:
7561+ // / case 2:
7562+ // / default:
7563+ // / // This is case 3
7564+ // / }
7565+ static bool simplifySwitchWhenUMin (SwitchInst *SI, IRBuilder<> &Builder) {
7566+ auto *Call = dyn_cast<IntrinsicInst>(SI->getCondition ());
7567+
7568+ if (!Call)
7569+ return false ;
7570+
7571+ if (Call->getIntrinsicID () != Intrinsic::umin)
7572+ return false ;
7573+
7574+ if (!SI->defaultDestUnreachable ())
7575+ return false ;
7576+
7577+ // Extract the constant operand from the intrinsic.
7578+ auto *Constant = dyn_cast<ConstantInt>(Call->getArgOperand (1 ));
7579+
7580+ if (!Constant) {
7581+ return false ;
7582+ }
7583+
7584+ for (auto Case = SI->case_begin (), e = SI->case_end (); Case != e; Case++) {
7585+ uint64_t CaseValue = Case->getCaseValue ()->getValue ().getZExtValue ();
7586+
7587+ // We found the case which is equal to the case's umin argument.
7588+ // We can make the case the default case.
7589+ if (Constant->equalsInt (CaseValue)) {
7590+ SI->setDefaultDest (Case->getCaseSuccessor ());
7591+ SI->removeCase (Case);
7592+ return true ;
7593+ }
7594+ }
7595+
7596+ return false ;
7597+ }
7598+
75437599// / Tries to transform switch of powers of two to reduce switch range.
75447600// / For example, switch like:
75457601// / switch (C) { case 1: case 2: case 64: case 128: }
@@ -7966,6 +8022,9 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
79668022 if (simplifyDuplicateSwitchArms (SI, DTU))
79678023 return requestResimplify ();
79688024
8025+ if (simplifySwitchWhenUMin (SI, Builder))
8026+ return requestResimplify ();
8027+
79698028 return false ;
79708029}
79718030
0 commit comments