combine-stack-adj.c (combine_stack_adjustments_for_block): Do nothing for stack adjus...
authorJeff Law <law@redhat.com>
Wed, 20 Sep 2017 05:43:28 +0000 (23:43 -0600)
committerJeff Law <law@gcc.gnu.org>
Wed, 20 Sep 2017 05:43:28 +0000 (23:43 -0600)
* combine-stack-adj.c (combine_stack_adjustments_for_block): Do
nothing for stack adjustments with REG_STACK_CHECK.
* sched-deps.c (parse_add_or_inc): Reject insns with
REG_STACK_CHECK from dependency breaking.
* config/i386/i386.c (pro_epilogue_adjust_stack): Return insn.
(ix86_adjust_satck_and_probe_stack_clash): Add REG_STACK_NOTEs.
* reg-notes.def (STACK_CHECK): New note.

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

From-SVN: r252999

gcc/ChangeLog
gcc/combine-stack-adj.c
gcc/config/i386/i386.c
gcc/reg-notes.def
gcc/sched-deps.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/stack-check-11.c [new file with mode: 0644]

index f9d3a419f1a5b88b43c45e6c65885faca4d7f334..8f3485bfc1d62ddf1feaf06375d8ffb4b758924a 100644 (file)
@@ -1,5 +1,13 @@
 2017-09-19  Jeff Law  <law@redhat.com>
 
+       * combine-stack-adj.c (combine_stack_adjustments_for_block): Do
+       nothing for stack adjustments with REG_STACK_CHECK.
+       * sched-deps.c (parse_add_or_inc): Reject insns with
+       REG_STACK_CHECK from dependency breaking.
+       * config/i386/i386.c (pro_epilogue_adjust_stack): Return insn.
+       (ix86_adjust_satck_and_probe_stack_clash): Add REG_STACK_NOTEs.
+       * reg-notes.def (STACK_CHECK): New note.
+
        * config/i386/i386.c (ix86_adjust_stack_and_probe_stack_clash): New.
        (ix86_expand_prologue): Dump stack clash info as needed.
        Call ix86_adjust_stack_and_probe_stack_clash as needed.
index 9ec14a3e44363f35f6419c38233ce5eebddd3458..82d6dba856fe374d3cb2e1b68f238217a507fabb 100644 (file)
@@ -508,6 +508,8 @@ combine_stack_adjustments_for_block (basic_block bb)
        continue;
 
       set = single_set_for_csa (insn);
+      if (set && find_reg_note (insn, REG_STACK_CHECK, NULL_RTX))
+       set = NULL_RTX;
       if (set)
        {
          rtx dest = SET_DEST (set);
index fdfe5951ca13b0cf7eda16d8e4a82f49f2bf0b80..d19c770d4cb6877f9a8fb9c69a7a24fa72a02c61 100644 (file)
@@ -13547,7 +13547,7 @@ ix86_add_queued_cfa_restore_notes (rtx insn)
    zero if %r11 register is live and cannot be freely used and positive
    otherwise.  */
 
-static void
+static rtx
 pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
                           int style, bool set_cfa)
 {
@@ -13638,6 +13638,7 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
       m->fs.sp_valid = valid;
       m->fs.sp_realigned = realigned;
     }
+  return insn;
 }
 
 /* Find an available register to be used as dynamic realign argument
@@ -13987,9 +13988,11 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size)
       for (i = probe_interval; i <= size; i += probe_interval)
        {
          /* Allocate PROBE_INTERVAL bytes.  */
-         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
-                                    GEN_INT (-probe_interval), -1,
-                                    m->fs.cfa_reg == stack_pointer_rtx);
+         rtx insn
+           = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+                                        GEN_INT (-PROBE_INTERVAL), -1,
+                                        m->fs.cfa_reg == stack_pointer_rtx);
+         add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
 
          /* And probe at *sp.  */
          emit_stack_probe (stack_pointer_rtx);
index 943eff41d307b1a5468edf9f8c6623024b55baff..a542990cde2d6d3c9e9c03185de14cb2c7e30bb2 100644 (file)
@@ -224,6 +224,10 @@ REG_NOTE (ARGS_SIZE)
    pseudo reg.  */
 REG_NOTE (RETURNED)
 
+/* Indicates the instruction is a stack check probe that should not
+   be combined with other stack adjustments.  */
+REG_NOTE (STACK_CHECK)
+
 /* Used to mark a call with the function decl called by the call.
    The decl might not be available in the call due to splitting of the call
    insn.  This note is a SYMBOL_REF.  */
index e7c4b879f55276b2f2f2c28eab30734fc33b5be4..a64e4e17bbc8115982d253d041032243e9506802 100644 (file)
@@ -4714,6 +4714,11 @@ parse_add_or_inc (struct mem_inc_info *mii, rtx_insn *insn, bool before_mem)
   if (RTX_FRAME_RELATED_P (insn) || !pat)
     return false;
 
+  /* Do not allow breaking data dependencies for insns that are marked
+     with REG_STACK_CHECK.  */
+  if (find_reg_note (insn, REG_STACK_CHECK, NULL))
+    return false;
+
   /* Result must be single reg.  */
   if (!REG_P (SET_DEST (pat)))
     return false;
index 55510b120b2eecfe9a31ac9f438623aee7185e75..d2eec19d4d077f0cc2920df176361423be4a872f 100644 (file)
@@ -1,5 +1,7 @@
 2017-09-19  Jeff Law  <law@redhat.com>
 
+       * gcc.target/i386/stack-check-11.c: New test.
+
        * gcc.dg/stack-check-4.c: New test.
        * gcc.dg/stack-check-5.c: New test.
        * gcc.dg/stack-check-6.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/stack-check-11.c b/gcc/testsuite/gcc.target/i386/stack-check-11.c
new file mode 100644 (file)
index 0000000..183103f
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-clash-protection" } */
+/* { dg-require-effective-target supports_stack_clash_protection } */
+
+extern void arf (unsigned long int *, unsigned long int *);
+void
+frob ()
+{
+  unsigned long int num[859];
+  unsigned long int den[859];
+  arf (den, num);
+}
+
+/* { dg-final { scan-assembler-times "subq" 4 } } */
+/* { dg-final { scan-assembler-times "orq" 3 } } */
+