https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119621
Bug ID: 119621 Summary: gcc doesn't have pattern matching to multiple switch Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: LYN_2019 at outlook dot com Target Milestone: --- see https://godbolt.org/z/cohbnnYME ```cpp #include <cstdint> #include <mmintrin.h> #include <nmmintrin.h> #include <utility> void f0(); void f1(); void f2(); void f3(); void f4(); void f5(); void f6(); void f7(); void f8(); void f9(); void f10(); void f11(); void f12(); void f13(); void f14(); void f15(); void f16(); void f17(); void f18(); void f19(); void f20(); void f21(); void f22(); void f23(); void f24(); void f25(); void f26(); void f27(); void f28(); void f29(); auto i2(::std::uint64_t a) { switch (a) { case 0: f0(); break; case 1: f1(); break; case 2: f2(); break; case 3: f3(); break; case 4: f4(); break; case 5: f5(); break; case 6: f6(); break; case 7: f7(); break; case 8: f8(); break; case 9: f9(); break; case 10: f10(); break; case 11: f11(); break; case 12: f12(); break; case 13: f13(); break; case 14: f14(); break; case 15: f15(); break; } switch(a) { case 16: f16(); break; case 17: f17(); break; case 18: f18(); break; case 19: f19(); break; case 20: f20(); break; case 21: f21(); break; case 22: f22(); break; case 23: f23(); break; case 24: f24(); break; } if (a == 25) f25(); } ``` -std=c++23 -O3 -march=znver5 -Wall -Wextra ```asm i2(unsigned long): cmp rdi, 15 ja .L2 jmp [QWORD PTR .L4[0+rdi*8]] .L4: .quad .L19 .quad .L18 .quad .L17 .quad .L16 .quad .L15 .quad .L14 .quad .L13 .quad .L12 .quad .L11 .quad .L10 .quad .L9 .quad .L8 .quad .L7 .quad .L6 .quad .L5 .quad .L3 .L5: jmp f14() .L3: jmp f15() .L19: jmp f0() .L18: jmp f1() .L17: jmp f2() .L16: jmp f3() .L15: jmp f4() .L14: jmp f5() .L13: jmp f6() .L12: jmp f7() .L11: jmp f8() .L10: jmp f9() .L9: jmp f10() .L8: jmp f11() .L7: jmp f12() .L6: jmp f13() .L2: lea rax, [rdi-16] cmp rax, 8 ja .L20 jmp [QWORD PTR .L22[0+rax*8]] .L22: .quad .L30 .quad .L29 .quad .L28 .quad .L27 .quad .L26 .quad .L25 .quad .L24 .quad .L23 .quad .L21 .L23: jmp f23() .L24: jmp f22() .L25: jmp f21() .L26: jmp f20() .L27: jmp f19() .L28: jmp f18() .L29: jmp f17() .L30: jmp f16() .L21: jmp f24() .L20: cmp rdi, 25 jne .L32 jmp f25() .L32: ret ``` should be optimize into one jmp table ``` asm i2(unsigned long): cmp rdi, 25 ja .LBB0_28 lea rax, [rip + .LJTI0_0] movsxd rcx, dword ptr [rax + 4*rdi] add rcx, rax jmp rcx .LBB0_2: jmp f0()@PLT .LBB0_18: jmp f16()@PLT .LBB0_16: jmp f14()@PLT .LBB0_13: jmp f11()@PLT .LBB0_6: jmp f4()@PLT .LBB0_14: jmp f12()@PLT .LBB0_11: jmp f9()@PLT .LBB0_27: jmp f25()@PLT .LBB0_26: jmp f24()@PLT .LBB0_4: jmp f2()@PLT .LBB0_17: jmp f15()@PLT .LBB0_5: jmp f3()@PLT .LBB0_9: jmp f7()@PLT .LBB0_3: jmp f1()@PLT .LBB0_19: jmp f17()@PLT .LBB0_22: jmp f20()@PLT .LBB0_7: jmp f5()@PLT .LBB0_23: jmp f21()@PLT .LBB0_15: jmp f13()@PLT .LBB0_8: jmp f6()@PLT .LBB0_20: jmp f18()@PLT .LBB0_12: jmp f10()@PLT .LBB0_10: jmp f8()@PLT .LBB0_24: jmp f22()@PLT .LBB0_21: jmp f19()@PLT .LBB0_25: jmp f23()@PLT .LBB0_28: ret .LJTI0_0: .long .LBB0_2-.LJTI0_0 .long .LBB0_3-.LJTI0_0 .long .LBB0_4-.LJTI0_0 .long .LBB0_5-.LJTI0_0 .long .LBB0_6-.LJTI0_0 .long .LBB0_7-.LJTI0_0 .long .LBB0_8-.LJTI0_0 .long .LBB0_9-.LJTI0_0 .long .LBB0_10-.LJTI0_0 .long .LBB0_11-.LJTI0_0 .long .LBB0_12-.LJTI0_0 .long .LBB0_13-.LJTI0_0 .long .LBB0_14-.LJTI0_0 .long .LBB0_15-.LJTI0_0 .long .LBB0_16-.LJTI0_0 .long .LBB0_17-.LJTI0_0 .long .LBB0_18-.LJTI0_0 .long .LBB0_19-.LJTI0_0 .long .LBB0_20-.LJTI0_0 .long .LBB0_21-.LJTI0_0 .long .LBB0_22-.LJTI0_0 .long .LBB0_23-.LJTI0_0 .long .LBB0_24-.LJTI0_0 .long .LBB0_25-.LJTI0_0 .long .LBB0_26-.LJTI0_0 .long .LBB0_27-.LJTI0_0 ```