aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2014-01-06 22:38:27 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-01-06 22:38:27 +0100
commit529a6471280e26d5ea558b83aa094ac847dbbec9 (patch)
tree31db34d335f3bdadd76045327720c59693b2856a /gcc
parent71d0d50aa3b292a1137dc2e7ed468aff24efdb83 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c16
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59644.c42
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;
+}