[llvm] [SimplifyCFG]: Switch on umin replaces default (PR #164097)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 18 09:56:03 PDT 2025


================
@@ -7540,6 +7540,62 @@ static bool reduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
   return true;
 }
 
+/// Tries to transform the switch when the condition is umin and a constant.
+/// In that case, the default branch can be replaced by the constant's branch.
+/// For example:
+/// switch(umin(a, 3)) {
+/// case 0:
+/// case 1:
+/// case 2:
+/// case 3:
+///   // ...
+/// default:
+///   unreachable
+/// }
+///
+/// Transforms into:
+///
+/// switch(umin(a, 3)) {
+/// case 0:
+/// case 1:
+/// case 2:
+/// default:
+///   // This is case 3
+/// }
+static bool simplifySwitchWhenUMin(SwitchInst *SI, IRBuilder<> &Builder) {
+  auto *Call = dyn_cast<IntrinsicInst>(SI->getCondition());
+
+  if (!Call)
+    return false;
+
+  if (Call->getIntrinsicID() != Intrinsic::umin)
+    return false;
+
+  if (!SI->defaultDestUnreachable())
+    return false;
+
+  // Extract the constant operand from the intrinsic.
+  auto *Constant = dyn_cast<ConstantInt>(Call->getArgOperand(1));
+
+  if (!Constant) {
+    return false;
+  }
+
+  for (auto Case = SI->case_begin(), e = SI->case_end(); Case != e; Case++) {
+    uint64_t CaseValue = Case->getCaseValue()->getValue().getZExtValue();
+
+    // We found the case which is equal to the case's umin argument.
+    // We can make the case the default case.
+    if (Constant->equalsInt(CaseValue)) {
+      SI->setDefaultDest(Case->getCaseSuccessor());
+      SI->removeCase(Case);
----------------
dtcxzyw wrote:

The dominator tree needs to be updated since it removes an edge from the current bb->default unreachable.

https://github.com/llvm/llvm-project/pull/164097


More information about the llvm-commits mailing list