[llvm] [SimplifyCFG] Transform switch to select when common bits uniquely identify one case (PR #145233)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 30 05:25:13 PDT 2025
================
@@ -6234,10 +6234,34 @@ 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(),
+ Condition->getType()->isSingleValueType());
+
+ 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) - (One << (ActiveBits - AndMask.popcount())) ==
----------------
spaits wrote:
I see. Maybe in this case a more generic pattern would be better.
Maybe `cmp eq and(%1, AndMask) AndMask` would be better.
We could identify cases like the following.
Let's consider the following case:
```
define i1 @range0to15(i8 range(i8 0, 15) %f) {
switch i8 %f, label %bb1 [
i8 6, label %bb2
i8 7, label %bb2
i8 14, label %bb2
i8 15, label %bb2
]
bb1:
br label %bb3
bb2:
br label %bb3
bb3:
%_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
ret i1 %_0.sroa.0.0
}
```
In the given range, that could be represented on 4 bits, 0110 would uniquely identify the pattern.
(
0110 = 6
0111 = 7
1110 = 14
1111 = 15
)
What do you think. Should I rather do this?
I think that would work with the cases we already have. (Maybe I am wrong. I am not that fluen with binary array ligic yet.)
https://github.com/llvm/llvm-project/pull/145233
More information about the llvm-commits
mailing list