Probes emitted by the common code routines still use a store.  Define
the "probe_stack" pattern to use a compare instead.

Bootstrapped and regression tested on s390x

Committed to mainline

gcc/ChangeLog:

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

        * config/s390/s390.c (s390_emit_stack_probe): Call the probe_stack
        expander.
        * config/s390/s390.md ("@probe_stack2<mode>", "probe_stack"): New
        expanders.

gcc/testsuite/ChangeLog:

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

        * gcc.target/s390/stack-clash-2.c: New test.
---
 gcc/ChangeLog                                 |  7 +++++++
 gcc/config/s390/s390.c                        |  7 +++----
 gcc/config/s390/s390.md                       | 16 +++++++++++++++-
 gcc/testsuite/ChangeLog                       |  4 ++++
 gcc/testsuite/gcc.target/s390/stack-clash-2.c | 17 +++++++++++++++++
 5 files changed, 46 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/stack-clash-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51d3e425ad5..5c2366e3671 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-05-14  Andreas Krebbel  <kreb...@linux.ibm.com>
+
+       * config/s390/s390.c (s390_emit_stack_probe): Call the probe_stack
+       expander.
+       * config/s390/s390.md ("@probe_stack2<mode>", "probe_stack"): New
+       expanders.
+
 2020-05-14  Andreas Krebbel  <kreb...@linux.ibm.com>
 
        * config/s390/s390.c (allocate_stack_space): Add missing updates
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index b4897256af5..4de3129f88e 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10946,10 +10946,9 @@ s390_prologue_plus_offset (rtx target, rtx reg, rtx 
offset, bool frame_related_p
 static void
 s390_emit_stack_probe (rtx addr)
 {
-  rtx tmp = gen_rtx_MEM (Pmode, addr);
-  MEM_VOLATILE_P (tmp) = 1;
-  s390_emit_compare (EQ, gen_rtx_REG (Pmode, 0), tmp);
-  emit_insn (gen_blockage ());
+  rtx mem = gen_rtx_MEM (Pmode, addr);
+  MEM_VOLATILE_P (mem) = 1;
+  emit_insn (gen_probe_stack (mem));
 }
 
 /* Use a runtime loop if we have to emit more probes than this.  */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 908de587e17..cd1c0634b71 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -11017,8 +11017,22 @@
 
   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
   DONE;
-})
+  })
+
+(define_expand "@probe_stack2<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+       (compare:CCZ (reg:P 0)
+                    (match_operand 0 "memory_operand")))
+   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
+  "")
 
+(define_expand "probe_stack"
+  [(match_operand 0 "memory_operand")]
+  ""
+{
+  emit_insn (gen_probe_stack2 (Pmode, operands[0]));
+  DONE;
+})
 
 ;
 ; setjmp instruction pattern.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8ff0bbcc85b..498ebb7f678 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-05-14  Andreas Krebbel  <kreb...@linux.ibm.com>
+
+       * gcc.target/s390/stack-clash-2.c: New test.
+
 2020-05-14  Andreas Krebbel  <kreb...@linux.ibm.com>
 
        * gcc.target/s390/stack-clash-1.c: New test.
diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-2.c 
b/gcc/testsuite/gcc.target/s390/stack-clash-2.c
new file mode 100644
index 00000000000..e554ad5ed0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/stack-clash-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z900 -fstack-clash-protection" } */
+
+extern void bar (char *);
+
+void
+foo ()
+{
+  char * mem = __builtin_alloca (20000);
+  bar (mem);
+}
+
+/* For alloca a common code routine emits the probes.  Make sure the
+   "probe_stack" expander is used in that case. We want to use mem
+   compares instead of stores.  */
+/* { dg-final { scan-assembler-times "cg\t" 5 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "c\t" 5 { target { ! lp64 } } } } */
-- 
2.17.1

Reply via email to