IBM Z: stack clash prot: add missing updates of last_probe_offset
authorAndreas Krebbel <krebbel@linux.ibm.com>
Thu, 14 May 2020 06:16:27 +0000 (08:16 +0200)
committerAndreas Krebbel <krebbel@linux.ibm.com>
Thu, 14 May 2020 06:16:27 +0000 (08:16 +0200)
After emitting probes in a loop last_probe_offset needs to be updated.
Not doing this usually assumes a too low distance to the last access
when emitting the remainder leading to stack probes being omitted.

gcc/ChangeLog:

2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>

* config/s390/s390.c (allocate_stack_space): Add missing updates
of last_probe_offset.

gcc/testsuite/ChangeLog:

2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>

* gcc.target/s390/stack-clash-1.c: New test.

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/stack-clash-1.c [new file with mode: 0644]

index 0b326ee09e8b11891b95070f5b4273d72e0b519d..51d3e425ad5c96e2dfcb1604b1f4206c2082cf60 100644 (file)
@@ -1,3 +1,8 @@
+2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * config/s390/s390.c (allocate_stack_space): Add missing updates
+       of last_probe_offset.
+
 2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * config/s390/s390.md ("allocate_stack"): Call
index 18332271ed7124d9145c967a09f8299ea95fc779..b4897256af5bcd401d3e58bbde4b904bae94e947 100644 (file)
@@ -10996,6 +10996,8 @@ allocate_stack_space (rtx size, HOST_WIDE_INT last_probe_offset,
                                                       stack_pointer_rtx,
                                                       offset));
                }
+             if (num_probes > 0)
+               last_probe_offset = INTVAL (offset);
              dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
            }
          else
@@ -11029,6 +11031,7 @@ allocate_stack_space (rtx size, HOST_WIDE_INT last_probe_offset,
              s390_prologue_plus_offset (stack_pointer_rtx, temp_reg,
                                         const0_rtx, true);
              temp_reg_clobbered_p = true;
+             last_probe_offset = INTVAL (offset);
              dump_stack_clash_frame_info (PROBE_LOOP, residual != 0);
            }
 
index bb3e4c86adcf4f57b750a0be61ec7b58a1991dcb..8ff0bbcc85b4f1cdad08527beb7326cf005ba45b 100644 (file)
@@ -1,3 +1,7 @@
+2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * gcc.target/s390/stack-clash-1.c: New test.
+
 2020-05-14  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * gcc.target/s390/stack-clash-3.c: New test.
diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-1.c b/gcc/testsuite/gcc.target/s390/stack-clash-1.c
new file mode 100644 (file)
index 0000000..3d29cab
--- /dev/null
@@ -0,0 +1,17 @@
+/* Make sure a stack probe is emitted also for the remaining bytes
+   after the loop probing the large chunk.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z9-ec -fstack-clash-protection" } */
+
+void large_stack() {
+  volatile int stack[8000];
+  int i;
+  for (i = 0; i < sizeof(stack) / sizeof(int); ++i)
+    stack[i] = i;
+}
+
+/* We use a compare for the stack probe.  There needs to be one inside
+   a loop and another for the remaining bytes.  */
+/* { dg-final { scan-assembler-times "cg\t" 2 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "c\t" 2 { target { ! lp64 } } } } */