https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103429
--- Comment #2 from Edward Rosten <ed at edwardrosten dot com> --- It is doing if-to-switch, but only really with N=5, and only if force-inline is set. I think this are two problems, one is that you need to force-inline in order to trigger if-to-switch. The other problem is that the if-to-switch conversion triggered only works well for exactly 5 conditions, otherwise it uses a mix of converted and unconverted. It doesn't appear to be doing binary tree generation, more like linear search Here's the asm for N=7: run(int): ret run_inline(int): test edi, edi je .L13 cmp edi, 1 je .L14 cmp edi, 6 ja .L3 mov edi, edi jmp [QWORD PTR .L8[0+rdi*8]] .L8: .quad .L3 .quad .L3 .quad .L12 .quad .L11 .quad .L10 .quad .L9 .quad .L7 .L13: jmp void f<0>() .L7: jmp void f<6>() .L12: jmp void f<2>() .L11: jmp void f<3>() .L10: jmp void f<4>() .L9: jmp void f<5>() .L14: jmp void f<1>() .L3: ret Note, it's essentially doing: if(i==0) f<0>(); else if(i==1) f<1>(); else if(i > 6) return; else switch(i){ case 0: case 1: return; case 2: f<2>(); return; case 3: f<3>(); return; case 4: f<4>(); return; case 5: f<5>(); return; case 6: f<6>(); return; } It's not doing binary searches. For, e.g. N%5 == 1, the structure is more like: if(i==0) f<0>(); else if(i > 5){ if(i-5 > 4){ if(i-11>4){ if(i-16 > 4){ // and so on, linearly } else switch(i-16){ //... } } else switch(i-11){ //... } } else switch(i-6){ //... } } else switch(i){ case 0: return; case 1: f<1>(); return; case 2: f<2>(); return; case 3: f<3>(); return; case 4: f<4>(); return; case 5: f<5>(); return; }