https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87205
Bug ID: 87205 Summary: Inefficient code generation for switch Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: pdimov at gmail dot com Target Milestone: --- For the following code: ``` void f( int x ); void h( unsigned ix ) { switch( ix ) { case 0: f(42); break; case 1: f(42); break; case 2: f(42); break; case 3: f(42); break; case 4: f(42); break; case 5: f(42); break; default: __builtin_unreachable(); } } ``` g++ 9.0 -O2, -O3 generates: ``` h(unsigned int): cmp edi, 5 jbe .L5 .L5: mov edi, 42 jmp f(int) ``` https://godbolt.org/z/4I_Chu The initial part that compares edi to 5 is redundant. At -O1 the result is a jump table that doesn't check edi, as expected: ``` h(unsigned int): sub rsp, 8 mov edi, edi jmp [QWORD PTR .L4[0+rdi*8]] ``` This is a simplified example; I've stripped the metaprogramming that produces it. :-) For comparison, g++ 8.2 produces ``` h(unsigned int): cmp edi, 5 ja .L2 mov edi, 42 jmp f(int) h(unsigned int) [clone .cold.0]: .L2: ```