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

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 1 01:52:15 PDT 2025


================
@@ -6234,10 +6234,33 @@ 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)
+      // In case, there are bits, that can only be present in the CaseValues we
+      // can transform the switch into a select if the conjunction of
+      // all the values uniquely identify the CaseValues.
+      APInt AndMask = APInt::getAllOnes(MinCaseVal->getBitWidth());
+
+      for (auto *Case : CaseValues) {
         if (Case->getValue().slt(MinCaseVal->getValue()))
           MinCaseVal = Case;
+        AndMask &= Case->getValue();
+      }
+
+      KnownBits Known = computeKnownBits(Condition, DL);
+      unsigned int ConditionWidth = Condition->getType()->getIntegerBitWidth();
+      APInt ActiveBits =
+          APInt(ConditionWidth, Known.countMaxActiveBits(), false);
+
+      APInt One(ConditionWidth, 1, false);
+      // To make sure, that the representation of the accepted values is
+      // actually unique we check, wheter the conjucted bits and the another
+      // conjuction with the input value will only be true for exactly CaseCount
+      // number times.
+      if ((One << (ActiveBits - AndMask.popcount())) == CaseCount) {
----------------
antoniofrighetto wrote:

Hmm, I think we still need to check that FreeBits won't be larger or equal than ConditionWidth though, if we go with getOneBitSet. See if you still like this:
```cpp
if (FreeBits < ConditionWidth) {
  APInt TopBit = APInt::getOneBitSet(ConditionWidth, FreeBits);
  if (TopBit == CaseCount) {
    // ...
  }
}
```

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


More information about the llvm-commits mailing list