https://bugs.llvm.org/show_bug.cgi?id=52482
Bug ID: 52482
Summary: Last case of switch generated as a comparison
Product: libraries
Version: trunk
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: Scalar Optimizations
Assignee: unassignedb...@nondot.org
Reporter: l...@rifkin.dev
CC: llvm-bugs@lists.llvm.org
Switch conversion fires on the following code:
void a(), b(), c(), d(), e();
void foo(int x) {
switch(x) {
case 0: a(); break;
case 1: b(); break;
case 2: c(); break;
case 3: d(); break;
case 4: e(); break;
default: __builtin_unreachable();
}
}
void bar(int x) {
if (x == 0) a();
else if (x == 1) b();
else if (x == 2) c();
else if (x == 3) d();
else if (x == 4) e();
else __builtin_unreachable();
}
But bar ends up being implemented with a switch, something like:
void bar(int x) {
if((unsigned)x > 3) {
e();
} else {
switch(x) {
case 0: a(); break;
case 1: b(); break;
case 2: c(); break;
case 3: d(); break;
default: __builtin_unreachable();
}
}
}
Case 4 is in its own branch rather than in the switch.
This appears to be due to SimplifyCFG transforming the last if-else in bar to
if(x == c) {
e();
} else {
__builtin_unreachable();
}
// into:
__builtin_assume(x == c);
e();
Then the if-else chain as a whole ends up being transformed to:
void bar(int x) {
switch(x) {
case 0: a(); break;
case 1: b(); break;
case 2: c(); break;
case 3: d(); break;
default:
__builtin_assume(x == 4);
e();
}
}
https://godbolt.org/z/qrYb1hnh7
I'm not sure how GCC deals with this (it does transform bar() correctly), I'm
interested what the best way to address this in LLVM will be.
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs