]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/59644 (r206243 miscompiles Linux kernel)
authorJakub Jelinek <jakub@gcc.gnu.org>
Mon, 6 Jan 2014 21:38:27 +0000 (22:38 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 6 Jan 2014 21:38:27 +0000 (22:38 +0100)
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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/cp/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr59644.c [new file with mode: 0644]

index 2a9dafaa1d00a4a81bc116d0385398424bf41a79..624c9fb8075e8b5e495746789ccdb4a392321cbf 100644 (file)
@@ -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
index 39891c96402db5020f4c953a8faa5db3d781f037..32b6418320fba1d28eae31d9d29fd4c34c1f53ef 100644 (file)
@@ -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;
index cdaab3684e1cb46975ba9e6e07b37d5d4e57cdb3..ab7489a0c1b7810b4b5365bcc96bdd7658a0006a 100644 (file)
@@ -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;
index 16abb96fd8e3082751ced79356dbecd7c6e9dfdc..99657a9f6d00e704c863c569325d8bd7ad75bff9 100644 (file)
@@ -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>
index 075e83ede09b775c48d62bcfffe1c08e9205aa68..b5a996f610b6e75d517acfec4c01693661c11cbe 100644 (file)
@@ -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 (file)
index 0000000..96006b3
--- /dev/null
@@ -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;
+}