[llvm] [SimplifyCFG]: Switch on umin replaces default (PR #164097)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 30 06:03:37 PDT 2025
================
@@ -7540,6 +7540,82 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
return true;
}
+/// Tries to transform the switch when the condition is umin with a constant.
+/// In that case, the default branch can be replaced by the constant's branch.
+/// This method also removes dead cases when the simplification cannot replace
+/// the default branch.
+///
+/// For example:
+/// switch(umin(a, 3)) {
+/// case 0:
+/// case 1:
+/// case 2:
+/// case 3:
+/// case 4:
+/// // ...
+/// default:
+/// unreachable
+/// }
+///
+/// Transforms into:
+///
+/// switch(a) {
+/// case 0:
+/// case 1:
+/// case 2:
+/// default:
+/// // This is case 3
+/// }
+static bool simplifySwitchWhenUMin(SwitchInst *SI, DomTreeUpdater *DTU) {
+ Value *A;
+ ConstantInt *Constant;
+
+ if (!match(SI->getCondition(), m_UMin(m_Value(A), m_ConstantInt(Constant))))
+ return false;
+
+ SmallVector<DominatorTree::UpdateType> Updates;
+ SwitchInstProfUpdateWrapper SIW(*SI);
+ BasicBlock *BB = SIW->getParent();
+
+ // Dead cases are removed even when the simplification fails.
+ // A case is dead when its value is higher than the Constant.
+ SmallVector<ConstantInt *, 4> DeadCases;
+ for (auto Case : SI->cases())
+ if (Case.getCaseValue()->getValue().ugt(Constant->getValue()))
+ DeadCases.push_back(Case.getCaseValue());
+
+ for (ConstantInt *DeadCaseVal : DeadCases) {
+ SwitchInst::CaseIt DeadCase = SIW->findCaseValue(DeadCaseVal);
+ BasicBlock *DeadCaseBB = DeadCase->getCaseSuccessor();
+ DeadCaseBB->removePredecessor(SIW->getParent());
+ SIW.removeCase(DeadCase);
+ Updates.push_back({DominatorTree::Delete, BB, DeadCaseBB});
+ }
----------------
dianqk wrote:
One nit:
```suggestion
for (auto I = SI->case_begin(), E = SI->case_end(); I != E;) {
if (!I->getCaseValue()->getValue().ugt(Constant->getValue())) {
++I;
continue;
}
BasicBlock *DeadCaseBB = I->getCaseSuccessor();
DeadCaseBB->removePredecessor(BB);
Updates.push_back({DominatorTree::Delete, BB, DeadCaseBB});
I = SI->removeCase(I);
E = SI->case_end();
}
```
https://github.com/llvm/llvm-project/pull/164097
More information about the llvm-commits
mailing list