https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84039
--- Comment #5 from hjl at gcc dot gnu.org <hjl at gcc dot gnu.org> --- Author: hjl Date: Mon Apr 16 19:08:14 2018 New Revision: 259421 URL: https://gcc.gnu.org/viewcvs?rev=259421&root=gcc&view=rev Log: i386: Add TARGET_INDIRECT_BRANCH_REGISTER For --- struct C { virtual ~C(); virtual void f(); }; void f (C *p) { p->f(); p->f(); } --- -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: _Z1fP1C: .LFB0: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movq (%rdi), %rax movq %rdi, %rbx jmp .LIND1 .LIND0: pushq 16(%rax) jmp __x86_indirect_thunk .LIND1: call .LIND0 movq (%rbx), %rax movq %rbx, %rdi popq %rbx .cfi_def_cfa_offset 8 movq 16(%rax), %rax jmp __x86_indirect_thunk_rax .cfi_endproc x86-64 is supposed to have asynchronous unwind tables by default, but there is nothing that reflects the change in the (relative) frame address after .LIND0. That region really has to be moved outside of the .cfi_startproc/.cfi_endproc bracket. This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect branch via register whenever -mindirect-branch= is used. Now, -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: _Z1fP1C: .LFB0: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movq (%rdi), %rax movq %rdi, %rbx movq 16(%rax), %rax call __x86_indirect_thunk_rax movq (%rbx), %rax movq %rbx, %rdi popq %rbx .cfi_def_cfa_offset 8 movq 16(%rax), %rax jmp __x86_indirect_thunk_rax .cfi_endproc so that "-mindirect-branch=thunk-extern" is equivalent to "-mindirect-branch=thunk-extern -mindirect-branch-register", which is used by Linux kernel. gcc/ Backport from mainline 2018-02-26 H.J. Lu <hongjiu...@intel.com> PR target/84039 * config/i386/constraints.md (Bs): Replace ix86_indirect_branch_register with TARGET_INDIRECT_BRANCH_REGISTER. (Bw): Likewise. * config/i386/i386.md (indirect_jump): Likewise. (tablejump): Likewise. (*sibcall_memory): Likewise. (*sibcall_value_memory): Likewise. Peepholes of indirect call and jump via memory: Likewise. (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER. (*sibcall_value_GOT_32): Likewise. * config/i386/predicates.md (indirect_branch_operand): Likewise. (GOT_memory_operand): Likewise. (call_insn_operand): Likewise. (sibcall_insn_operand): Likewise. (GOT32_symbol_operand): Likewise. * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New. gcc/testsuite/ Backport from mainline 2018-02-26 H.J. Lu <hongjiu...@intel.com> PR target/84039 * gcc.target/i386/indirect-thunk-1.c: Updated. * gcc.target/i386/indirect-thunk-2.c: Likewise. * gcc.target/i386/indirect-thunk-3.c: Likewise. * gcc.target/i386/indirect-thunk-4.c: Likewise. * gcc.target/i386/indirect-thunk-5.c: Likewise. * gcc.target/i386/indirect-thunk-6.c: Likewise. * gcc.target/i386/indirect-thunk-7.c: Likewise. * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. * gcc.target/i386/ret-thunk-9.c: Likewise. * gcc.target/i386/ret-thunk-10.c: Likewise. * gcc.target/i386/ret-thunk-11.c: Likewise. * gcc.target/i386/ret-thunk-12.c: Likewise. * gcc.target/i386/ret-thunk-13.c: Likewise. * gcc.target/i386/ret-thunk-14.c: Likewise. * gcc.target/i386/ret-thunk-15.c: Likewise. Modified: branches/gcc-6-branch/gcc/ChangeLog branches/gcc-6-branch/gcc/config/i386/constraints.md branches/gcc-6-branch/gcc/config/i386/i386.h branches/gcc-6-branch/gcc/config/i386/i386.md branches/gcc-6-branch/gcc/config/i386/predicates.md branches/gcc-6-branch/gcc/testsuite/ChangeLog branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-10.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-11.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-12.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-13.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-14.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-15.c branches/gcc-6-branch/gcc/testsuite/gcc.target/i386/ret-thunk-9.c