From 70e18df76ed2ccce4f6695b7f848d25dfa31ce0e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 13 Jun 2018 11:20:23 +0000 Subject: [PATCH] re PR target/86048 (.seh_savexmm offset is negative error when compiling libpng) PR target/86048 * config/i386/winnt.c (i386_pe_seh_cold_init): Do not emit negative offsets for register save directives. Emit a second batch of save directives, if need be, when the function accesses prior frames. From-SVN: r261544 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/winnt.c | 25 +++++++++++++++++++++---- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/i386/pr86048.c | 26 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr86048.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34eb1d9..103877a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-06-13 Eric Botcazou + + PR target/86048 + * config/i386/winnt.c (i386_pe_seh_cold_init): Do not emit negative + offsets for register save directives. Emit a second batch of save + directives, if need be, when the function accesses prior frames. + 2018-06-12 Claudiu Zissulescu * config/arc/fpu.md (fmasf4): Force operand to register. diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 3a857f9..89e4b6e 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -922,11 +922,14 @@ i386_pe_seh_cold_init (FILE *f, const char *name) fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (seh->reg_offset[regno] > 0) + if (seh->reg_offset[regno] > 0 && seh->reg_offset[regno] <= alloc_offset) { - fputs ((SSE_REGNO_P (regno) ? "\t.seh_savexmm\t" - : GENERAL_REGNO_P (regno) ? "\t.seh_savereg\t" - : (gcc_unreachable (), "")), f); + if (SSE_REGNO_P (regno)) + fputs ("\t.seh_savexmm\t", f); + else if (GENERAL_REGNO_P (regno)) + fputs ("\t.seh_savereg\t", f); + else + gcc_unreachable (); print_reg (gen_rtx_REG (DImode, regno), 0, f); fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", alloc_offset - seh->reg_offset[regno]); @@ -949,6 +952,20 @@ i386_pe_seh_cold_init (FILE *f, const char *name) offset = seh->sp_offset - alloc_offset; if (offset > 0 && offset < SEH_MAX_FRAME_SIZE) fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset); + + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (seh->reg_offset[regno] > alloc_offset) + { + if (SSE_REGNO_P (regno)) + fputs ("\t.seh_savexmm\t", f); + else if (GENERAL_REGNO_P (regno)) + fputs ("\t.seh_savereg\t", f); + else + gcc_unreachable (); + print_reg (gen_rtx_REG (DImode, regno), 0, f); + fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", + seh->sp_offset - seh->reg_offset[regno]); + } } fputs ("\t.seh_endprologue\n", f); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb680c7..8d5d405 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-06-13 Eric Botcazou + + * gcc.target/i386/pr86048.c: New test. + 2018-06-12 Claudiu Zissulescu * gcc.target/arc/fma-1.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr86048.c b/gcc/testsuite/gcc.target/i386/pr86048.c new file mode 100644 index 0000000..cd73579 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr86048.c @@ -0,0 +1,26 @@ +/* PR target/86048 */ +/* { dg-do assemble } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target return_address } */ + +extern void abort (void); + +void *foo (unsigned int *data, unsigned int len) +{ + unsigned int local_data[128]; + + if (len > 128) + abort (); + + for (unsigned int i = 0; i < len; i++) + local_data[i] = data[i] + data[len - 1 - i] * 2; + + void *ret = __builtin_frame_address (0); + + for (unsigned int i = 0; i < len; i++) + ret = ret + local_data[i] % 8; + + __asm__ __volatile__ ("" : : : "%xmm6"); + + return ret; +} -- 2.7.4