[Committed] S/390: Fix PR84332 ICE with stack clash protection

Message ID 20180809070842.GA8437@maggie
State New
Headers show
Series
  • [Committed] S/390: Fix PR84332 ICE with stack clash protection
Related show

Commit Message

Andreas Krebbel Aug. 9, 2018, 7:08 a.m.
Our implementation of the stack probe requires the probe interval to
be used as displacement in an address operand.  The maximum probe
interval currently is 64k.  This would exceed short displacements.
Trim that value down to 4k if that happens.  This might result in too
many probes being generated only on the oldest supported machine level
z900.

Bootstrapped and regression tested on s390x with z900 and z13 defaults.

gcc/ChangeLog:

2018-08-09  Andreas Krebbel  <krebbel@linux.ibm.com>

	PR target/84332
	* config/s390/s390.c (s390_option_override_internal): Reduce the
	stack-clash-protection-probe-interval param if it would be too big
	for z900.

gcc/testsuite/ChangeLog:

2018-08-09  Andreas Krebbel  <krebbel@linux.ibm.com>

	PR target/84332
	* gcc.target/s390/pr84332.c: New testcase.

Patch

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index d533a3fcb4e..d5511d01192 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -14983,6 +14983,17 @@  s390_option_override_internal (struct gcc_options *opts,
   else if (opts->x_s390_stack_guard)
     error ("-mstack-guard implies use of -mstack-size");
 
+  /* Our implementation of the stack probe requires the probe interval
+     to be used as displacement in an address operand.  The maximum
+     probe interval currently is 64k.  This would exceed short
+     displacements.  Trim that value down to 4k if that happens.  This
+     might result in too many probes being generated only on the
+     oldest supported machine level z900.  */
+  if (!DISP_IN_RANGE ((1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL))))
+    set_param_value ("stack-clash-protection-probe-interval", 12,
+		     opts->x_param_values,
+		     opts_set->x_param_values);
+
 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
   if (!TARGET_LONG_DOUBLE_128_P (opts_set->x_target_flags))
     opts->x_target_flags |= MASK_LONG_DOUBLE_128;
diff --git a/gcc/testsuite/gcc.target/s390/pr84332.c b/gcc/testsuite/gcc.target/s390/pr84332.c
new file mode 100644
index 00000000000..3dec99f62c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr84332.c
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=z900 -fstack-clash-protection --param stack-clash-protection-probe-interval=16" } */
+
+struct b
+{
+  char a[65536];
+};
+
+void c (void) { struct b d; }