> On Sun, Jan 28, 2018 at 11:56 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > > On Sat, Jan 27, 2018 at 2:12 PM, H.J. Lu <hongjiu...@intel.com> wrote: > >> 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 when -mindirect-branch=thunk-extern 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 > >> > >> Now "-mindirect-branch=thunk-extern" is equivalent to > >> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is > >> used by Linux kernel. > >> > >> Tested on i686 and x86-64. OK for trunk? > >> > >> Thanks. > >> > >> H.J. > >> ---- > >> gcc/ > >> > >> 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. > >> * config/i386/i386.opt: 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. > >> > > > > Here is the updated patch to disallow *sibcall_GOT_32 and > > *sibcall_value_GOT_32 > > for TARGET_INDIRECT_BRANCH_REGISTER. > > > > Tested on i686 and x86-64. OK for trunk? > > > > Hi Jan, > > https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html > > Is OK for trunk?
I see that using register makes the problem go away and pushing address to stack seemed bit odd anyway. However how does this work on other types of thunk? Honza