re PR target/84128 (i686: Stack spilling in -fstack-clash-protection prologue neglect...
authorJeff Law <law@gcc.gnu.org>
Thu, 1 Feb 2018 16:22:56 +0000 (09:22 -0700)
committerJeff Law <law@gcc.gnu.org>
Thu, 1 Feb 2018 16:22:56 +0000 (09:22 -0700)
PR target/84128
* config/i386/i386.c (release_scratch_register_on_entry): Add new
OFFSET and RELEASE_VIA_POP arguments.  Use SP+OFFSET to restore
the scratch if RELEASE_VIA_POP is false.
(ix86_adjust_stack_and_probe_stack_clash): Un-constify SIZE.
If we have to save a temporary register, decrement SIZE appropriately.
Pass new arguments to release_scratch_register_on_entry.
(ix86_adjust_stack_and_probe): Likewise.
(ix86_emit_probe_stack_range): Pass new arguments to
release_scratch_register_on_entry.

PR target/84128
* gcc.target/i386/pr84128.c: New test.

From-SVN: r257303

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

index 2f44038f514a392dbff43de5848d5be68b06212f..25a1beefe70ae18f6698f9096d3b90780f2b3c55 100644 (file)
@@ -1,3 +1,16 @@
+2018-02-01  Jeff Law  <law@redhat.com>
+
+       PR target/84128
+       * config/i386/i386.c (release_scratch_register_on_entry): Add new
+       OFFSET and RELEASE_VIA_POP arguments.  Use SP+OFFSET to restore
+       the scratch if RELEASE_VIA_POP is false.
+       (ix86_adjust_stack_and_probe_stack_clash): Un-constify SIZE.
+       If we have to save a temporary register, decrement SIZE appropriately.
+       Pass new arguments to release_scratch_register_on_entry.
+       (ix86_adjust_stack_and_probe): Likewise.
+       (ix86_emit_probe_stack_range): Pass new arguments to
+       release_scratch_register_on_entry.
+
 2018-02-01  Uros Bizjak  <ubizjak@gmail.com>
 
        PR rtl-optimization/84157
        * common.opt (falign-functions=, falign-jumps=, falign-labels=,
        falign-loops=): Add Optimization flag.
 
-2017-01-30  Jeff Law  <law@redhat.com>
+2018-01-30  Jeff Law  <law@redhat.com>
 
        PR target/84064
        * i386.c (ix86_adjust_stack_and_probe_stack_clash): New argument
        * config/m68k/m68k.c (m68k_promote_function_mode): New function.
        (TARGET_PROMOTE_FUNCTION_MODE): New macro.
 
-2017-01-24  Jeff Law  <law@redhat.com>
+2018-01-24  Jeff Law  <law@redhat.com>
 
        PR target/83994
        * i386.c (get_probe_interval): Move to earlier point.
        * doc/sourcebuild.texi (arm_fp16fml_neon_ok, arm_fp16fml_neon):
        Document new effective target and option set.
 
-2017-01-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+2018-01-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm-cpus.in (armv8_4): New feature.
        (ARMv8_4a): New fgroup.
        of first and second elements in UNSPEC_VPERMR vector.
        (altivec_expand_vec_perm_le): Likewise.
 
-2017-01-08  Jeff Law  <law@redhat.com>
+2018-01-08  Jeff Law  <law@redhat.com>
 
        PR rtl-optimizatin/81308
        * tree-switch-conversion.c (cfg_altered): New file scoped static.
        range_int_cst_p rather than !symbolic_range_p before calling
        extract_range_from_multiplicative_op_1.
 
-2017-01-04  Jeff Law  <law@redhat.com>
+2018-01-04  Jeff Law  <law@redhat.com>
 
        * tree-ssa-math-opts.c (execute_cse_reciprocals_1): Remove
        redundant test in assertion.
        * expmed.c (make_tree): Build VECTOR_CSTs directly from the
        CONST_VECTOR encoding.
 
-2017-01-03  Jakub Jelinek  <jakub@redhat.com>
+2018-01-03  Jakub Jelinek  <jakub@redhat.com>
            Jeff Law  <law@redhat.com>
 
        PR target/83641
        (sprintf_dom_walker::compute_format_length): Same.
        (try_substitute_return_value): Same.
 
-2017-01-03  Jeff Law  <law@redhat.com>
+2018-01-03  Jeff Law  <law@redhat.com>
 
        PR middle-end/83654
        * explow.c (anti_adjust_stack_and_probe_stack_clash): Test a
index deb7e8ff617d23560a8cf8ccae1a269eae7431da..9943be145ae426c365b829e849c77559f6459038 100644 (file)
@@ -12567,22 +12567,39 @@ get_scratch_register_on_entry (struct scratch_reg *sr)
     }
 }
 
-/* Release a scratch register obtained from the preceding function.  */
+/* Release a scratch register obtained from the preceding function.
+
+   If RELEASE_VIA_POP is true, we just pop the register off the stack
+   to release it.  This is what non-Linux systems use with -fstack-check.
+
+   Otherwise we use OFFSET to locate the saved register and the
+   allocated stack space becomes part of the local frame and is
+   deallocated by the epilogue.  */
 
 static void
-release_scratch_register_on_entry (struct scratch_reg *sr)
+release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
+                                  bool release_via_pop)
 {
   if (sr->saved)
     {
-      struct machine_function *m = cfun->machine;
-      rtx x, insn = emit_insn (gen_pop (sr->reg));
+      if (release_via_pop)
+       {
+         struct machine_function *m = cfun->machine;
+         rtx x, insn = emit_insn (gen_pop (sr->reg));
 
-      /* The RTX_FRAME_RELATED_P mechanism doesn't know about pop.  */
-      RTX_FRAME_RELATED_P (insn) = 1;
-      x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
-      x = gen_rtx_SET (stack_pointer_rtx, x);
-      add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
-      m->fs.sp_offset -= UNITS_PER_WORD;
+         /* The RX FRAME_RELATED_P mechanism doesn't know about pop.  */
+         RTX_FRAME_RELATED_P (insn) = 1;
+         x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
+         x = gen_rtx_SET (stack_pointer_rtx, x);
+         add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
+         m->fs.sp_offset -= UNITS_PER_WORD;
+       }
+      else
+       {
+         rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
+         x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
+         emit_insn (x);
+       }
     }
 }
 
@@ -12597,7 +12614,7 @@ release_scratch_register_on_entry (struct scratch_reg *sr)
    pushed on the stack.  */
 
 static void
-ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
+ix86_adjust_stack_and_probe_stack_clash (HOST_WIDE_INT size,
                                         const bool int_registers_saved)
 {
   struct machine_function *m = cfun->machine;
@@ -12713,6 +12730,12 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
       struct scratch_reg sr;
       get_scratch_register_on_entry (&sr);
 
+      /* If we needed to save a register, then account for any space
+        that was pushed (we are not going to pop the register when
+        we do the restore).  */
+      if (sr.saved)
+       size -= UNITS_PER_WORD;
+
       /* Step 1: round SIZE down to a multiple of the interval.  */
       HOST_WIDE_INT rounded_size = size & -probe_interval;
 
@@ -12761,7 +12784,9 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
                                   m->fs.cfa_reg == stack_pointer_rtx);
       dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
 
-      release_scratch_register_on_entry (&sr);
+      /* This does not deallocate the space reserved for the scratch
+        register.  That will be deallocated in the epilogue.  */
+      release_scratch_register_on_entry (&sr, size, false);
     }
 
   /* Make sure nothing is scheduled before we are done.  */
@@ -12774,7 +12799,7 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
    pushed on the stack.  */
 
 static void
-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
+ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
                             const bool int_registers_saved)
 {
   /* We skip the probe for the first interval + a small dope of 4 words and
@@ -12847,6 +12872,11 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
 
       get_scratch_register_on_entry (&sr);
 
+      /* If we needed to save a register, then account for any space
+        that was pushed (we are not going to pop the register when
+        we do the restore).  */
+      if (sr.saved)
+       size -= UNITS_PER_WORD;
 
       /* Step 1: round SIZE to the previous multiple of the interval.  */
 
@@ -12906,7 +12936,9 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
                                                    (get_probe_interval ()
                                                     + dope))));
 
-      release_scratch_register_on_entry (&sr);
+      /* This does not deallocate the space reserved for the scratch
+        register.  That will be deallocated in the epilogue.  */
+      release_scratch_register_on_entry (&sr, size, false);
     }
 
   /* Even if the stack pointer isn't the CFA register, we need to correctly
@@ -13055,7 +13087,7 @@ ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
                                                       sr.reg),
                                         rounded_size - size));
 
-      release_scratch_register_on_entry (&sr);
+      release_scratch_register_on_entry (&sr, size, true);
     }
 
   /* Make sure nothing is scheduled before we are done.  */
index da557b80629b49ae88d14c7b7edf92b1af23a2ce..8ce7c29050cc72d411345c2ee2ae6cb5452288b5 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-30  Jeff Law  <law@redhat.com>
+
+       PR target/84128
+       * gcc.target/i386/pr84128.c: New test.
+
 2018-02-01  Georg-Johann Lay  <avr@gjlay.de>
 
        * gcc.dg/tree-ssa/vrp111.c (dg-options): Add
        PR target/84064
        * gcc.target/i386/pr84064: New test.
 
-2017-01-30  Thomas Koenig  <tkoenig@gcc.gnu.org>
+2018-01-30  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/84134
        * gfortran.dg/data_implied_do_2.f90: New test.
        PR tree-optimization/84057
        * gcc.dg/graphite/pr84057.c: New testcase.
 
-2017-01-29  Thomas Koenig  <tkoenig@gcc.gnu.org>
+2018-01-29  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/84073
        * gfortran.dg/bind_c_usage_31.f90: New test.
        check_effective_target_arm_fp16fml_neon_ok,
        add_options_for_arm_fp16fml_neon): New procedures.
 
-2017-01-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+2018-01-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * gcc.target/arm/multilib.exp: Add some -march=armv8.4-a
        combination tests.
        PR c++/83734
        * g++.dg/cpp0x/pr83734.C: New test.
 
-2017-01-09 Carl Love  <cel@us.ibm.com>
+2018-01-09 Carl Love  <cel@us.ibm.com>
 
        * gcc.target/powerpc/builtins-1.c (main): Add tests for vec_mergee and
        vec_mergeo builtins with float, double, long long, unsigned long long,
diff --git a/gcc/testsuite/gcc.target/i386/pr84128.c b/gcc/testsuite/gcc.target/i386/pr84128.c
new file mode 100644 (file)
index 0000000..a8323fd
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -march=i686 -mtune=generic -fstack-clash-protection" } */
+/* { dg-require-effective-target ia32 } */
+
+__attribute__ ((noinline, noclone, weak, regparm (3)))
+int
+f1 (long arg0, int (*pf) (long, void *))
+{
+  unsigned char buf[32768];
+  return pf (arg0, buf);
+}
+
+__attribute__ ((noinline, noclone, weak))
+int
+f2 (long arg0, void *ignored)
+{
+  if (arg0 != 17)
+    __builtin_abort ();
+  return 19;
+}
+
+int
+main (void)
+{
+  if (f1 (17, f2) != 19)
+    __builtin_abort ();
+  return 0;
+}
+
+