[llvm] [CodeGen] Optimize switch on ucmp/scmp to branch sequence (PR #176582)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 26 06:16:54 PST 2026


================
@@ -8127,9 +8125,88 @@ bool CodeGenPrepare::optimizeSwitchPhiConstants(SwitchInst *SI) {
   return Changed;
 }
 
-bool CodeGenPrepare::optimizeSwitchInst(SwitchInst *SI) {
+// Converts switch(ucmp(x,y)) into direct branches to avoid materializing the
+// -1/0/1 value.
+static bool optimizeSwitchOnCompare(SwitchInst *SI, Function &F,
+                                    const TargetTransformInfo &TTI,
+                                    ModifyDT &ModifiedDT) {
+  Value *Cond = SI->getCondition();
+
+  if (auto *Cast = dyn_cast<CastInst>(Cond)) {
+    if (Cast->getOpcode() == Instruction::ZExt ||
+        Cast->getOpcode() == Instruction::SExt) {
+      Cond = Cast->getOperand(0);
+    }
+  }
+
+  auto *II = dyn_cast<CmpIntrinsic>(Cond);
+  if (!II)
+    return false;
+
+  Value *LHS = II->getOperand(0);
+  Value *RHS = II->getOperand(1);
+
+  // 1. Map Targets (-1 -> Less, 0 -> Equal, 1 -> Greater)
+  BasicBlock *DestLess = SI->getDefaultDest();
+  BasicBlock *DestEqual = SI->getDefaultDest();
+  BasicBlock *DestGreater = SI->getDefaultDest();
+
+  unsigned IntrinsicWidth = II->getType()->getScalarSizeInBits();
+
+  for (auto Case : SI->cases()) {
+    APInt Val = Case.getCaseValue()->getValue();
+
+    if (Val.getBitWidth() > IntrinsicWidth)
+      Val = Val.trunc(IntrinsicWidth);
----------------
nikic wrote:

This is not quite right. E.g. you could be looking through zext and have a case with one of the high bits set. That case would just be dead, while you'll make it live here. You need to check that the top bits match the sext/zext.

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


More information about the llvm-commits mailing list