ENDBR must be the first instruction of a function. This patch queues ENDBR if we need to put the profiling counter call before the prologue and generate ENDBR before the profiling counter call.
OK for trunk if there is no regressions? H.J. --- gcc/ PR target/82699 * config/i386/i386.c (ix86_profile_before_prologue): Add a prototype. (rest_of_insert_endbranch): Set endbr_queued_at_entrance to true and don't insert ENDBR if ix86_profile_before_prologue () returns true. (x86_function_profiler): Insert ENDBR if endbr_queued_at_entrance is true. gcc/testsuite/ PR target/82699 * gcc.target/i386/pr82699-1.c: New file. * gcc.target/i386/pr82699-2.c: Likewise. * gcc.target/i386/pr82699-3.c: Likewise. * gcc.target/i386/pr82699-4.c: Likewise. --- gcc/config/i386/i386.c | 18 ++++++++++++++---- gcc/config/i386/i386.h | 3 +++ gcc/testsuite/gcc.target/i386/pr82699-1.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/pr82699-2.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/pr82699-3.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/pr82699-4.c | 11 +++++++++++ 6 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-3.c create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-4.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d2188ad6086..4e6936cd987 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -101,6 +101,7 @@ static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool); static bool ix86_save_reg (unsigned int, bool, bool); static bool ix86_function_naked (const_tree); static bool ix86_notrack_prefixed_insn_p (rtx); +static bool ix86_profile_before_prologue (void); #ifndef CHECK_STACK_LIMIT #define CHECK_STACK_LIMIT (-1) @@ -2590,11 +2591,16 @@ rest_of_insert_endbranch (void) TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))) && !cgraph_node::get (cfun->decl)->only_called_directly_p ()) { - cet_eb = gen_nop_endbr (); + if (ix86_profile_before_prologue ()) + cfun->machine->endbr_queued_at_entrance = true; + else + { + cet_eb = gen_nop_endbr (); - bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; - insn = BB_HEAD (bb); - emit_insn_before (cet_eb, insn); + bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; + insn = BB_HEAD (bb); + emit_insn_before (cet_eb, insn); + } } bb = 0; @@ -40427,6 +40433,10 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) { const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE : MCOUNT_NAME); + + if (cfun->machine->endbr_queued_at_entrance) + fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32"); + if (TARGET_64BIT) { #ifndef NO_PROFILE_COUNTERS diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 27fc9f08cc7..925557d32cb 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2581,6 +2581,9 @@ struct GTY(()) machine_function { /* Nonzero if the function places outgoing arguments on stack. */ BOOL_BITFIELD outgoing_args_on_stack : 1; + /* If true, ENDBR is queued at function entrance. */ + BOOL_BITFIELD endbr_queued_at_entrance : 1; + /* During prologue/epilogue generation, the current frame state. Otherwise, the frame state at the end of the prologue. */ struct machine_frame_state fs; diff --git a/gcc/testsuite/gcc.target/i386/pr82699-1.c b/gcc/testsuite/gcc.target/i386/pr82699-1.c new file mode 100644 index 00000000000..4fc404753e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr82699-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */ +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */ + +extern int bar (int); + +int +foo (int i) +{ + return bar (i); +} diff --git a/gcc/testsuite/gcc.target/i386/pr82699-2.c b/gcc/testsuite/gcc.target/i386/pr82699-2.c new file mode 100644 index 00000000000..4fb9cb9e68b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr82699-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */ +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */ + +extern int bar (int); + +int +foo (int i) +{ + return bar (i); +} diff --git a/gcc/testsuite/gcc.target/i386/pr82699-3.c b/gcc/testsuite/gcc.target/i386/pr82699-3.c new file mode 100644 index 00000000000..92d84ee4ab5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr82699-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */ +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */ + +extern int bar (int); + +int +foo (int i) +{ + return bar (i); +} diff --git a/gcc/testsuite/gcc.target/i386/pr82699-4.c b/gcc/testsuite/gcc.target/i386/pr82699-4.c new file mode 100644 index 00000000000..415ce3b913a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr82699-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */ +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */ + +extern int bar (int); + +int +foo (int i) +{ + return bar (i); +} -- 2.13.6