i386: Add TARGET_INDIRECT_BRANCH_REGISTER
authorH.J. Lu <hongjiu.lu@intel.com>
Mon, 26 Feb 2018 17:00:46 +0000 (17:00 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Mon, 26 Feb 2018 17:00:46 +0000 (09:00 -0800)
commitc2c601b2c0e406cde6f94a905635d4fcdf51d3de
tree5accf513fe52169d1b14dfc30b5cf254fda89dda
parent94e16982e6f26d9d0db20bdeed01741b1cb1018f
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/

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/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.

gcc/testsuite/

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.

From-SVN: r258001
45 files changed:
gcc/ChangeLog
gcc/config/i386/constraints.md
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
gcc/testsuite/gcc.target/i386/ret-thunk-10.c
gcc/testsuite/gcc.target/i386/ret-thunk-11.c
gcc/testsuite/gcc.target/i386/ret-thunk-12.c
gcc/testsuite/gcc.target/i386/ret-thunk-13.c
gcc/testsuite/gcc.target/i386/ret-thunk-14.c
gcc/testsuite/gcc.target/i386/ret-thunk-15.c
gcc/testsuite/gcc.target/i386/ret-thunk-9.c