On Tue, Jun 21, 2022 at 3:50 AM Uros Bizjak via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Mon, Jun 20, 2022 at 8:14 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > On Tue, May 10, 2022 at 9:25 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > Mark a function with SYMBOL_FLAG_FUNCTION_ENDBR when inserting ENDBR at > > > function entry. Skip the 4-byte ENDBR when emitting a direct call/jmp > > > to a local function with ENDBR at function entry. > > > > > > This has been tested on Linux kernel. > > > > > > gcc/ > > > > > > PR target/102953 > > > * config/i386/i386-features.cc > > > (rest_of_insert_endbr_and_patchable_area): Set > > > SYMBOL_FLAG_FUNCTION_ENDBR when inserting ENDBR. > > > * config/i386/i386.cc (ix86_print_operand): Skip the 4-byte ENDBR > > > when calling the local function with ENDBR at function entry. > > > * config/i386/i386.h (SYMBOL_FLAG_FUNCTION_ENDBR): New. > > > (SYMBOL_FLAG_FUNCTION_ENDBR_P): Likewise. > > > > > > gcc/testsuite/ > > > > > > PR target/102953 > > > * gcc.target/i386/pr102953-1.c: New test. > > > * gcc.target/i386/pr102953-2.c: Likewise. The patch looks good to me. For direct call, endbr64 should not be used as a marker, right? > > > --- > > > gcc/config/i386/i386-features.cc | 2 ++ > > > gcc/config/i386/i386.cc | 11 +++++++- > > > gcc/config/i386/i386.h | 5 ++++ > > > gcc/testsuite/gcc.target/i386/pr102953-1.c | 25 ++++++++++++++++++ > > > gcc/testsuite/gcc.target/i386/pr102953-2.c | 30 ++++++++++++++++++++++ > > > 5 files changed, 72 insertions(+), 1 deletion(-) > > > create mode 100644 gcc/testsuite/gcc.target/i386/pr102953-1.c > > > create mode 100644 gcc/testsuite/gcc.target/i386/pr102953-2.c > > > > > > diff --git a/gcc/config/i386/i386-features.cc > > > b/gcc/config/i386/i386-features.cc > > > index 6fe41c3c24f..3ca1131ed59 100644 > > > --- a/gcc/config/i386/i386-features.cc > > > +++ b/gcc/config/i386/i386-features.cc > > > @@ -1979,6 +1979,8 @@ rest_of_insert_endbr_and_patchable_area (bool > > > need_endbr, > > > || (TARGET_DLLIMPORT_DECL_ATTRIBUTES > > > && DECL_DLLIMPORT_P (cfun->decl)))) > > > { > > > + rtx symbol = XEXP (DECL_RTL (cfun->decl), 0); > > > + SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_FUNCTION_ENDBR; > > > if (crtl->profile && flag_fentry) > > > { > > > /* Queue ENDBR insertion to x86_function_profiler. > > > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc > > > index 86752a6516a..ad1de239bef 100644 > > > --- a/gcc/config/i386/i386.cc > > > +++ b/gcc/config/i386/i386.cc > > > @@ -13787,7 +13787,16 @@ ix86_print_operand (FILE *file, rtx x, int code) > > > else if (flag_pic || MACHOPIC_INDIRECT) > > > output_pic_addr_const (file, x, code); > > > else > > > - output_addr_const (file, x); > > > + { > > > + /* Skip ENDBR when emitting a direct call/jmp to a local > > > + function with ENDBR at function entry. */ > > > + if (code == 'P' > > > + && GET_CODE (x) == SYMBOL_REF > > > + && SYMBOL_REF_LOCAL_P (x) > > > + && SYMBOL_FLAG_FUNCTION_ENDBR_P (x)) > > > + x = gen_rtx_PLUS (Pmode, x, GEN_INT (4)); > > > + output_addr_const (file, x); > > > + } > > > } > > > } > > > > > > diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h > > > index 363082ba47b..7a6317fea57 100644 > > > --- a/gcc/config/i386/i386.h > > > +++ b/gcc/config/i386/i386.h > > > @@ -2792,6 +2792,11 @@ extern GTY(()) tree ms_va_list_type_node; > > > #define SYMBOL_REF_STUBVAR_P(X) \ > > > ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_STUBVAR) != 0) > > > > > > +/* Flag to mark a function with ENDBR at entry. */ > > > +#define SYMBOL_FLAG_FUNCTION_ENDBR (SYMBOL_FLAG_MACH_DEP << 5) > > > +#define SYMBOL_FLAG_FUNCTION_ENDBR_P(X) \ > > > + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FUNCTION_ENDBR) != 0) > > > + > > > extern void debug_ready_dispatch (void); > > > extern void debug_dispatch_window (int); > > > > > > diff --git a/gcc/testsuite/gcc.target/i386/pr102953-1.c > > > b/gcc/testsuite/gcc.target/i386/pr102953-1.c > > > new file mode 100644 > > > index 00000000000..2afad391baf > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/pr102953-1.c > > > @@ -0,0 +1,25 @@ > > > +/* { dg-do compile { target { ! *-*-darwin* } } } */ > > > +/* { dg-options "-O2 -fno-pic -fplt -fcf-protection" } */ > > > + > > > +extern int func (int); > > > + > > > +extern int i; > > > + > > > +__attribute__ ((noclone, noinline, noipa)) > > > +static int > > > +bar (int x) > > > +{ > > > + if (x == 0) > > > + return x; > > > + return bar (x - 1) + func (x); > > > +} > > > + > > > +void * > > > +foo (void) > > > +{ > > > + i = bar (2); > > > + return bar; > > > +} > > > + > > > +/* { dg-final { scan-assembler-times {call\t_?bar\+4\M} 2 } } */ > > > +/* { dg-final { scan-assembler-times {call\t_?func\M} 1 } } */ > > > diff --git a/gcc/testsuite/gcc.target/i386/pr102953-2.c > > > b/gcc/testsuite/gcc.target/i386/pr102953-2.c > > > new file mode 100644 > > > index 00000000000..5b8d517f4f2 > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/pr102953-2.c > > > @@ -0,0 +1,30 @@ > > > +/* { dg-do compile { target { ! *-*-darwin* } } } */ > > > +/* { dg-options "-O2 -fno-pic -fplt -fcf-protection" } */ > > > + > > > +static int bar (int x); > > > +extern int func (int); > > > + > > > +int > > > +foo (int i) > > > +{ > > > + return bar (i); > > > +} > > > + > > > +void * > > > +bar_p (void) > > > +{ > > > + return bar; > > > +} > > > + > > > +__attribute__ ((noclone, noinline, noipa)) > > > +static int > > > +bar (int x) > > > +{ > > > + if (x == 0) > > > + return x; > > > + return bar (x - 1) + func (x); > > > +} > > > + > > > +/* { dg-final { scan-assembler-times {call\t_?bar\+4\M} 1 } } */ > > > +/* { dg-final { scan-assembler-times {jmp\t_?bar\+4\M} 1 } } */ > > > +/* { dg-final { scan-assembler-times {call\t_?func\M} 1 } } */ > > > -- > > > 2.35.1 > > > > > > > PING. > > CET stuff will have to be reviewed by someone else. > > Uros.
-- BR, Hongtao