https://gcc.gnu.org/bugzilla/show_bug.cgi?id=35775
--- Comment #3 from Thomas Koenig <tkoenig at gcc dot gnu.org> --- We now get $ cat tailcall.c void bar(void); void baz(void); void foo(int a) { if (a) bar(); else baz(); } $ gcc -S -Os tailcall.c $ cat tailcall.s .file "tailcall.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc testl %edi, %edi je .L2 jmp bar .L2: jmp baz .cfi_endproc .LFE0: .size foo, .-foo .ident "GCC: (GNU) 9.0.1 20190414 (experimental)" .section .note.GNU-stack,"",@progbits so the original test case is fixed. With a slightly more complex test case, we now get $ cat tailcall2.s .file "tailcall2.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc pushq %rcx .cfi_def_cfa_offset 16 call gargle testl %eax, %eax je .L2 popq %rdx .cfi_remember_state .cfi_def_cfa_offset 8 jmp bar .L2: .cfi_restore_state popq %rax .cfi_def_cfa_offset 8 jmp baz .cfi_endproc .LFE0: .size foo, .-foo .ident "GCC: (GNU) 9.0.1 20190414 (experimental)" .section .note.GNU-stack,"",@progbits so the problem is still present in this case (using two different registers seems strange, but it should not matter).