diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-06 22:38:27 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-06 22:38:27 +0100 |
commit | 529a6471280e26d5ea558b83aa094ac847dbbec9 (patch) | |
tree | 31db34d335f3bdadd76045327720c59693b2856a /gcc | |
parent | 71d0d50aa3b292a1137dc2e7ed468aff24efdb83 (diff) | |
download | gcc-529a6471280e26d5ea558b83aa094ac847dbbec9.zip gcc-529a6471280e26d5ea558b83aa094ac847dbbec9.tar.gz gcc-529a6471280e26d5ea558b83aa094ac847dbbec9.tar.bz2 |
re PR target/59644 (r206243 miscompiles Linux kernel)
PR target/59644
* config/i386/i386.h (struct machine_function): Add
no_drap_save_restore field.
* config/i386/i386.c (ix86_save_reg): Use
!cfun->machine->no_drap_save_restore instead of
crtl->stack_realign_needed.
(ix86_finalize_stack_realign_flags): Don't clear drap_reg unless
this function clears frame_pointer_needed. Set
cfun->machine->no_drap_save_restore if clearing frame_pointer_needed
and DRAP reg is needed.
* gcc.target/i386/pr59644.c: New test.
From-SVN: r206375
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 16 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 3 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59644.c | 42 |
6 files changed, 70 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a9dafa..624c9fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-01-06 Jakub Jelinek <jakub@redhat.com> + + PR target/59644 + * config/i386/i386.h (struct machine_function): Add + no_drap_save_restore field. + * config/i386/i386.c (ix86_save_reg): Use + !cfun->machine->no_drap_save_restore instead of + crtl->stack_realign_needed. + (ix86_finalize_stack_realign_flags): Don't clear drap_reg unless + this function clears frame_pointer_needed. Set + cfun->machine->no_drap_save_restore if clearing frame_pointer_needed + and DRAP reg is needed. + 2014-01-06 Marek Polacek <polacek@redhat.com> PR c/57773 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 39891c9..32b6418 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9281,7 +9281,7 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return) if (crtl->drap_reg && regno == REGNO (crtl->drap_reg) - && crtl->stack_realign_needed) + && !cfun->machine->no_drap_save_restore) return true; return (df_regs_ever_live_p (regno) @@ -10519,18 +10519,6 @@ ix86_finalize_stack_realign_flags (void) return; } - /* If drap has been set, but it actually isn't live at the start - of the function and !stack_realign, there is no reason to set it up. */ - if (crtl->drap_reg && !stack_realign) - { - basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; - if (! REGNO_REG_SET_P (DF_LR_IN (bb), REGNO (crtl->drap_reg))) - { - crtl->drap_reg = NULL_RTX; - crtl->need_drap = false; - } - } - /* If the only reason for frame_pointer_needed is that we conservatively assumed stack realignment might be needed, but in the end nothing that needed the stack alignment had been spilled, clear frame_pointer_needed @@ -10584,6 +10572,8 @@ ix86_finalize_stack_realign_flags (void) crtl->need_drap = false; } } + else + cfun->machine->no_drap_save_restore = true; frame_pointer_needed = false; stack_realign = false; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index cdaab36..ab7489a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2419,6 +2419,9 @@ struct GTY(()) machine_function { stack below the return address. */ BOOL_BITFIELD static_chain_on_stack : 1; + /* If true, it is safe to not save/restore DRAP register. */ + BOOL_BITFIELD no_drap_save_restore : 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/cp/ChangeLog b/gcc/cp/ChangeLog index 16abb96..99657a9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,19 +1,19 @@ 2014-01-06 Adam Butcher <adam@jessamine.co.uk> PR c++/59635 - * cp/lambda.c (maybe_add_lambda_conv_op): Handle marking conversion + * lambda.c (maybe_add_lambda_conv_op): Handle marking conversion function as unimplemented for generic lambdas with varargs. PR c++/59636 - * cp/parser.c (cp_parser_template_parameter): Early out with + * parser.c (cp_parser_template_parameter): Early out with error_mark_node if parameter declaration was not parsed. PR c++/59629 - * cp/parser.c (cp_parser_lambda_expression): Save/reset/restore + * parser.c (cp_parser_lambda_expression): Save/reset/restore auto_is_implicit_function_template_parm_p around lambda body. PR c++/59638 - * cp/parser.c (cp_parser_init_declarator): Undo fully implicit + * parser.c (cp_parser_init_declarator): Undo fully implicit template parameter list when declarator is not a function. 2014-01-03 Marc Glisse <marc.glisse@inria.fr> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 075e83e..b5a996f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-06 Jakub Jelinek <jakub@redhat.com> + + PR target/59644 + * gcc.target/i386/pr59644.c: New test. + 2014-01-06 Marek Polacek <polacek@redhat.com> PR c/57773 diff --git a/gcc/testsuite/gcc.target/i386/pr59644.c b/gcc/testsuite/gcc.target/i386/pr59644.c new file mode 100644 index 0000000..96006b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59644.c @@ -0,0 +1,42 @@ +/* PR target/59644 */ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -ffreestanding -mno-sse -mpreferred-stack-boundary=3 -maccumulate-outgoing-args -mno-red-zone" } */ + +/* This test uses __builtin_trap () instead of e.g. abort, + because due to -mpreferred-stack-boundary=3 it should not call + any library function from within main (). */ + +#include <stdarg.h> + +__attribute__((noinline, noclone)) +int +bar (int x, int y, int z, int w, const char *fmt, va_list ap) +{ + if (x != 1 || y != 2 || z != 3 || w != 4) + __builtin_trap (); + if (fmt[0] != 'f' || fmt[1] != 'o' || fmt[2] != 'o' || fmt[3]) + __builtin_trap (); + if (va_arg (ap, int) != 5 || va_arg (ap, int) != 6 + || va_arg (ap, long long) != 7LL) + __builtin_trap (); + return 9; +} + +__attribute__((noinline, noclone, optimize ("Os"))) +int +foo (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + int r = bar (1, 2, 3, 4, fmt, ap); + va_end (ap); + return r; +} + +int +main () +{ + if (foo ("foo", 5, 6, 7LL) != 9) + __builtin_trap (); + return 0; +} |