[llvm] [SimplifyCFG] Transform switch to select when common bits uniquely identify one case (PR #145233)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 2 07:55:50 PDT 2025


================
@@ -6234,10 +6234,35 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
     // case 0,2,8,10 -> Cond & 0b1..0101 == 0 ? result : default
     if (isPowerOf2_32(CaseCount)) {
       ConstantInt *MinCaseVal = CaseValues[0];
-      // Find mininal value.
-      for (auto *Case : CaseValues)
+      // If there are bits that are set exclusively by CaseValues, we
+      // can transform the switch into a select if the conjunction of
+      // all the values uniquely identify CaseValues.
+      APInt AndMask = APInt::getAllOnes(MinCaseVal->getBitWidth());
+
+      // Find the minimum value and compute the and of all the case values.
+      for (auto *Case : CaseValues) {
         if (Case->getValue().slt(MinCaseVal->getValue()))
           MinCaseVal = Case;
+        AndMask &= Case->getValue();
+      }
+      KnownBits Known = computeKnownBits(Condition, DL);
+
+      if (!AndMask.isZero() && Known.getMaxValue().uge(AndMask)) {
+        // Compute the number of bits that are free to vary.
+        unsigned FreeBits = Known.countMaxActiveBits() - AndMask.popcount();
+        // Compute 2^FreeBits in order to check whether all the possible
+        // combinations of the free bits matches the number of cases.
+        APInt TopBit = APInt::getOneBitSet(
+            Condition->getType()->getIntegerBitWidth(), FreeBits);
+
+        if (TopBit == CaseCount) {
----------------
dtcxzyw wrote:

```suggestion
        if (FreeBits == Log2_32(CaseCount)) {
```

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


More information about the llvm-commits mailing list