https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59521
--- Comment #9 from Martin Liška <marxin at gcc dot gnu.org> --- (In reply to Yuri Gribov from comment #8) > Created attachment 41737 [details] > New draft patch > > How about this? I added edge attribute for builtin_expect and later used it > in emit_case_decision_tree to emit expected comparison prior to decision > tree for other case values. > > With this patch GCC optimizes original example. If it's not too ugly I'll do > proper testing and send to gcc-patches. The patch works for me for the described case, but does not for PGO, which should do the same based on real numbers: $ cat pr59521-profile.c #include <stdio.h> void f(int ch) { switch (ch) { case 100: puts("100"); break; case 10: puts("10"); break; case 1: puts("1"); break; } } int main() { for (int i = 0; i < 10000; i++) { int v; if (i % 100 == 0) v = 100; else if(i % 10 == 0) v = 10; else v = 1; f(v); } } $ gcc pr59521-profile.c -fprofile-generate && ./a.out && gcc pr59521-profile.c -fprofile-use -S -fdump-tree-optimized=/dev/stdout ... f (int ch) { <bb 2> [100.00%] [count: 10000]: switch (ch_2(D)) <default: <L3> [0.00%] [count: 0], case 1: <L2> [90.00%] [count: 9000], case 10: <L1> [9.00%] [count: 900], case 100: <L0> [1.00%] [count: 100]> ... But assembly looks as follows: cmpl $10, %eax je .L3 cmpl $100, %eax je .L4 cmpl $1, %eax je .L5 jmp .L6 Just a small note, Honza's planning to rewrite switch expansion to happen on tree level. Maybe (hopefully) such transformations will be easier on tree level?