Issue |
56087
|
Summary |
[SimplifyCFG] Chain of ICMPs not optimised to switch
|
Labels |
llvm:optimizations,
missed-optimization
|
Assignees |
|
Reporter |
davidbolvansky
|
`
bool cond_as_ret(int c) {
bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
return r;
}
int cond_in_select(int c) {
bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
return r ? 1 : -1;
}
int cond_in_br(int c) {
bool r = (c == 'h' | c == 'e' | c == 'l' | c == 'o' | c == 'w' | c == '\0');
if(r) return 1;
else return -1;
}`
`
define dso_local zeroext i1 @cond_as_ret(i32 noundef %0) local_unnamed_addr #0 {
%2 = icmp eq i32 %0, 101
%3 = and i32 %0, -5
%4 = icmp eq i32 %3, 104
%5 = or i1 %2, %4
%6 = icmp eq i32 %0, 111
%7 = or i1 %6, %5
%8 = icmp eq i32 %0, 119
%9 = or i1 %8, %7
%10 = icmp eq i32 %0, 0
%11 = or i1 %10, %9
ret i1 %11
}
define dso_local i32 @cond_in_select(i32 noundef %0) local_unnamed_addr #0 {
%2 = icmp eq i32 %0, 101
%3 = and i32 %0, -5
%4 = icmp eq i32 %3, 104
%5 = or i1 %2, %4
%6 = icmp eq i32 %0, 111
%7 = or i1 %6, %5
%8 = icmp eq i32 %0, 119
%9 = or i1 %8, %7
%10 = icmp eq i32 %0, 0
%11 = or i1 %10, %9
%12 = select i1 %11, i32 1, i32 -1
ret i32 %12
}
define dso_local i32 @cond_in_br(i32 noundef %0) local_unnamed_addr #0 {
switch i32 %0, label %2 [
i32 119, label %3
i32 111, label %3
i32 108, label %3
i32 104, label %3
i32 101, label %3
i32 0, label %3
]
2: ; preds = %1
br label %3
3: ; preds = %1, %1, %1, %1, %1, %1, %2
%4 = phi i32 [ -1, %2 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ], [ 1, %1 ]
ret i32 %4
}`
cond_in_br case is handled by SimplifyCFGOpt::SimplifyBranchOnICmpChain. Generalization would help to handle more forms.
GCC emits very nice code for all three functions, something what we want as well.
Godbolt: https://godbolt.org/z/YYYhK4fcG
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs