Skip to content

Commit fba6d47

Browse files
committed
[SimplifyCFG]: Remove unreachable when switch with umin
1 parent b4b7aae commit fba6d47

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)