http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54364
Bug #: 54364 Summary: Tail call jumps not threaded Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: ste...@gcc.gnu.org Consider: #undef ONE #undef TEN #undef HUN #define ONE(X) \ void use##X (int); #define TEN(X) \ ONE(X##0) ONE(X##1) ONE(X##2) ONE(X##3) ONE(X##4) \ ONE(X##5) ONE(X##6) ONE(X##7) ONE(X##8) ONE(X##9) #define HUN \ TEN(0) TEN(1) TEN(2) TEN(3) TEN(4) \ TEN(5) TEN(6) TEN(7) TEN(8) TEN(9) TEN(1) #undef ONE #undef TEN #undef HUN #define ONE(X) \ case 1##X##1 ... 1##X##2: use##X (c); break; #define TEN(X) \ ONE(X##0) ONE(X##1) ONE(X##2) ONE(X##3) ONE(X##4) \ ONE(X##5) ONE(X##6) ONE(X##7) ONE(X##8) ONE(X##9) #define HUN \ TEN(0) TEN(1) TEN(2) TEN(3) TEN(4) \ TEN(5) TEN(6) TEN(7) TEN(8) TEN(9) void foo (int c) { switch (c) { TEN(1) default: break; } } With r190601, "cc1 -Os -fno-jump-tables", this compiles to: .file "t.c" .text .globl foo .type foo, @function foo: .LFB0: cmpl $1142, %edi jg .L13 cmpl $1141, %edi jge .L8 cmpl $1112, %edi jg .L14 cmpl $1111, %edi jge .L11 leal -1101(%rdi), %eax cmpl $1, %eax ja .L1 jmp .L16 .L14: cmpl $1121, %edi jl .L1 cmpl $1122, %edi jle .L10 leal -1131(%rdi), %eax cmpl $1, %eax ja .L1 jmp .L17 .L13: cmpl $1172, %edi jg .L15 cmpl $1171, %edi jge .L5 cmpl $1151, %edi jl .L1 cmpl $1152, %edi jle .L7 leal -1161(%rdi), %eax cmpl $1, %eax ja .L1 jmp .L18 .L15: cmpl $1181, %edi jl .L1 cmpl $1182, %edi jle .L4 leal -1191(%rdi), %eax cmpl $1, %eax ja .L1 jmp .L19 .L16: jmp use10 .L11: jmp use11 .L10: jmp use12 .L17: jmp use13 .L8: jmp use14 .L7: jmp use15 .L18: jmp use16 .L5: jmp use17 .L4: jmp use18 .L19: jmp use19 .L1: ret .LFE0: .size foo, .-foo .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0 .byte 0x3 .string "zR" .uleb128 0x1 .sleb128 -8 .uleb128 0x10 .uleb128 0x1 .byte 0x3 .byte 0xc .uleb128 0x7 .uleb128 0x8 .byte 0x90 .uleb128 0x1 .align 8 .LECIE1: .LSFDE1: .long .LEFDE1-.LASFDE1 .LASFDE1: .long .LASFDE1-.Lframe1 .long .LFB0 .long .LFE0-.LFB0 .uleb128 0 .align 8 .LEFDE1: .ident "GCC: (GNU) 4.8.0 20120822 (experimental) [trunk \ revision 190601]" .section .note.GNU-stack,"",@progbits Note the missed "jump threading" opportunities from the case decision tree to the tail calls. The RTL for one of the missed tail calls looks like this: ... # BLOCK 11 freq:157 seq:9 # PRED: 10 [50.0%] (FALLTHRU) # SUCC: 25 [100.0%] # 145 pc=L144 jmp .L17 # 145 jump [length = 2] ... # BLOCK 25 freq:909 seq:23 # PRED: 11 [100.0%] .L17: # SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL) # 79 call <...> # REG_DEAD: di:SI jmp use13 # 79 *sibcall [length = 5] I am guessing that jumps to calls are not handled as jump threading opportunities because the call_insn isn't recognized as just a jump.