When assembler directives for DWARF frame unwind is enabled, generate the .cfi_undefined directive for unsaved callee-saved registers which have been used in the function.
gcc/ PR target/38534 * config/i386/i386.cc (ix86_post_cfi_startproc): New. (TARGET_ASM_POST_CFI_STARTPROC): Likewise. gcc/testsuite/ PR target/38534 * gcc.target/i386/no-callee-saved-19.c: New test. * gcc.target/i386/no-callee-saved-20.c: Likewise. * gcc.target/i386/pr38534-7.c: Likewise. * gcc.target/i386/pr38534-8.c: Likewise. --- gcc/config/i386/i386.cc | 37 +++++++++++++++++++ .../gcc.target/i386/no-callee-saved-19.c | 17 +++++++++ .../gcc.target/i386/no-callee-saved-20.c | 12 ++++++ gcc/testsuite/gcc.target/i386/pr38534-7.c | 18 +++++++++ gcc/testsuite/gcc.target/i386/pr38534-8.c | 13 +++++++ 5 files changed, 97 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-19.c create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-20.c create mode 100644 gcc/testsuite/gcc.target/i386/pr38534-7.c create mode 100644 gcc/testsuite/gcc.target/i386/pr38534-8.c diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index b3e7c74846e..d4c10a5ef9b 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -22662,6 +22662,40 @@ x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, flag_force_indirect_call = saved_flag_force_indirect_call; } +/* Implement TARGET_ASM_POST_CFI_STARTPROC. Triggered after a + .cfi_startproc directive is emitted into the assembly file. + When assembler directives for DWARF frame unwind is enabled, + output the .cfi_undefined directive for unsaved callee-saved + registers which have been used in the function. */ + +void +ix86_post_cfi_startproc (FILE *f, tree) +{ + if ((cfun->machine->call_saved_registers + == TYPE_NO_CALLEE_SAVED_REGISTERS) + && dwarf2out_do_cfi_asm ()) + for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (df_regs_ever_live_p (i) + && !fixed_regs[i] + && !call_used_regs[i] + && !STACK_REGNO_P (i) + && !MMX_REGNO_P (i)) + { + if (LEGACY_INT_REGNO_P (i)) + { + if (TARGET_64BIT) + asm_fprintf (f, "\t.cfi_undefined r%s\n", + hi_reg_name[i]); + else + asm_fprintf (f, "\t.cfi_undefined e%s\n", + hi_reg_name[i]); + } + else + asm_fprintf (f, "\t.cfi_undefined %s\n", + hi_reg_name[i]); + } +} + static void x86_file_start (void) { @@ -26281,6 +26315,9 @@ static const scoped_attribute_specs *const ix86_attribute_table[] = #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk +#undef TARGET_ASM_POST_CFI_STARTPROC +#define TARGET_ASM_POST_CFI_STARTPROC ix86_post_cfi_startproc + #undef TARGET_ASM_FILE_START #define TARGET_ASM_FILE_START x86_file_start diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-19.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-19.c new file mode 100644 index 00000000000..60a492cffd3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-19.c @@ -0,0 +1,17 @@ +/* { dg-do assemble { target *-*-linux* *-*-gnu* } } */ +/* { dg-options "-save-temps -march=tigerlake -O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +#include "no-callee-saved-1.c" + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined rbx" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined rbp" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r15" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined ebx" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined ebp" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/no-callee-saved-20.c b/gcc/testsuite/gcc.target/i386/no-callee-saved-20.c new file mode 100644 index 00000000000..fc94778824a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/no-callee-saved-20.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target cfi } } */ +/* { dg-options "-march=tigerlake -O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +__attribute__ ((no_callee_saved_registers)) +void +foo (void) +{ +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-not ".cfi_undefined" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr38534-7.c b/gcc/testsuite/gcc.target/i386/pr38534-7.c new file mode 100644 index 00000000000..01dbd77cd75 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr38534-7.c @@ -0,0 +1,18 @@ +/* { dg-do assemble { target *-*-linux* *-*-gnu* } } */ +/* { dg-options "-save-temps -march=tigerlake -O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +#include "pr38534-1.c" + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined rbx" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined rbp" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r12" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r13" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r14" 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined r15" 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".cfi_undefined r15" { target x32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined ebx" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined esi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined edi" 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times ".cfi_undefined ebp" 1 { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr38534-8.c b/gcc/testsuite/gcc.target/i386/pr38534-8.c new file mode 100644 index 00000000000..020c1512db1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr38534-8.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target cfi } } */ +/* { dg-options "-march=tigerlake -O2 -mtune-ctrl=^prologue_using_move,^epilogue_using_move" } */ + +void +__attribute__((noreturn)) +no_return_to_caller (void) +{ + while (1); +} + +/* { dg-final { scan-assembler-not "push" } } */ +/* { dg-final { scan-assembler-not "pop" } } */ +/* { dg-final { scan-assembler-not ".cfi_undefined" } } */ -- 2.43.0