This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] S/390: Fix PR84332 ICE with stack clash protection
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 9 Aug 2018 09:08:42 +0200
- Subject: [Committed] S/390: Fix PR84332 ICE with stack clash protection
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.
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; }