[llvm] [SimplifyCFG] When only one case value is missing, replace default with that case (PR #76669)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 1 02:19:23 PST 2024
================
@@ -5609,10 +5612,30 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
Known.getBitWidth() - (Known.Zero | Known.One).popcount();
assert(NumUnknownBits <= Known.getBitWidth());
if (HasDefault && DeadCases.empty() &&
- NumUnknownBits < 64 /* avoid overflow */ &&
- SI->getNumCases() == (1ULL << NumUnknownBits)) {
- createUnreachableSwitchDefault(SI, DTU);
- return true;
+ NumUnknownBits < 64 /* avoid overflow */) {
+ uint64_t AllNumCases = 1ULL << NumUnknownBits;
+ if (SI->getNumCases() == AllNumCases) {
+ createUnreachableSwitchDefault(SI, DTU);
+ return true;
+ }
+ // When only one case value is missing, replace default with that case.
+ if (SI->getNumCases() == AllNumCases - 1) {
+ uint64_t MissingCaseVal = 0;
+ for (const auto &Case : SI->cases())
+ MissingCaseVal ^= Case.getCaseValue()->getValue().getLimitedValue();
+ for (uint64_t I = 0; I < AllNumCases; I++)
+ MissingCaseVal ^= I;
----------------
dtcxzyw wrote:
I don't think the approach to find the missing case value is correct.
An example:
```
%val = and i32 %a, 1
%shl = shl nuw i32 %val, 2
%caseval = or disjoint %shl, 11
switch i32 %x, label %default [
i32 11, label %case0
; i32 15, label %case1 ; Missing case val
]
```
```
NumUnknownBits = 1
AllNumCases = 2
MissingCaseVal = 11 ^ 1 = 10 != 15
```
For other cases with `NumUnknownBits > 1`, your approach just happens to produce the right result because `(0 ^ 1 ^ ... ^ (2^k - 1)) = 0` when `k > 1`.
```suggestion
assert(NumUnknownBits > 1 && "Should be canonicalized to a branch");
```
https://github.com/llvm/llvm-project/pull/76669
More information about the llvm-commits
mailing list