i386.c (ix86_emit_restore_reg_using_pop): Prototype.
authorJeff Law <law@redhat.com>
Fri, 3 Nov 2017 20:30:53 +0000 (14:30 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 3 Nov 2017 20:30:53 +0000 (14:30 -0600)
* config/i386/i386.c (ix86_emit_restore_reg_using_pop): Prototype.
(ix86_adjust_stack_and_probe_stack_clash): Use a push/pop sequence
to probe at the start of a noreturn function.

* gcc.target/i386/stack-check-12.c: New test.

From-SVN: r254396

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/stack-check-12.c [new file with mode: 0644]

index 98cd5a41b65f2cadacc81adff27eccf055e79320..99f8aba9f6b8275a136d4482a17f86580e06b418 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-03  Jeff Law  <law@redhat.com>
+
+       * config/i386/i386.c (ix86_emit_restore_reg_using_pop): Prototype.
+       (ix86_adjust_stack_and_probe_stack_clash): Use a push/pop sequence
+       to probe at the start of a noreturn function.
+
 2017-11-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/78821
index 25b28a1a0886aa76615e1796c526df2fc390aedc..1b837554609850393bb0d419edb1e354f9edba49 100644 (file)
@@ -101,6 +101,8 @@ static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
 static bool ix86_save_reg (unsigned int, bool, bool);
 static bool ix86_function_naked (const_tree);
 static bool ix86_notrack_prefixed_insn_p (rtx);
+static void ix86_emit_restore_reg_using_pop (rtx);
+
 
 #ifndef CHECK_STACK_LIMIT
 #define CHECK_STACK_LIMIT (-1)
@@ -12124,8 +12126,14 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size)
      we just probe when we cross PROBE_INTERVAL.  */
   if (TREE_THIS_VOLATILE (cfun->decl))
     {
-      emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
-                                      -GET_MODE_SIZE (word_mode)));
+      /* We can safely use any register here since we're just going to push
+        its value and immediately pop it back.  But we do try and avoid
+        argument passing registers so as not to introduce dependencies in
+        the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
+      rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
+      rtx_insn *insn = emit_insn (gen_push (dummy_reg));
+      RTX_FRAME_RELATED_P (insn) = 1;
+      ix86_emit_restore_reg_using_pop (dummy_reg);
       emit_insn (gen_blockage ());
     }
 
index 69d8b6b510d77c7913625ed6ea75b34ec9639d88..4cc2cedc0dce22347b63842041b9115ed60d6188 100644 (file)
@@ -1,3 +1,7 @@
+2017-11-03  Jeff Law  <law@redhat.com>
+
+       * gcc.target/i386/stack-check-12.c: New test.
+
 2017-11-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/78821
diff --git a/gcc/testsuite/gcc.target/i386/stack-check-12.c b/gcc/testsuite/gcc.target/i386/stack-check-12.c
new file mode 100644 (file)
index 0000000..cb69bb0
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection -mtune=generic" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+
+__attribute__ ((noreturn)) void exit (int);
+
+__attribute__ ((noreturn)) void
+f (void)
+{
+  asm volatile ("nop" ::: "edi");
+  exit (1);
+}
+
+/* { dg-final { scan-assembler-not "or\[ql\]" } } */
+/* { dg-final { scan-assembler "pushl  %esi" { target ia32 } } } */
+/* { dg-final { scan-assembler "popl   %esi" { target ia32 } } }*/
+/* { dg-final { scan-assembler "pushq  %rax" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "popq   %rax" { target { ! ia32 } } } }*/
+