summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-05 23:45:32 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-05 23:45:32 +0000
commit70c912cff7f00414cad5c3dee2ab969f7f4acf08 (patch)
tree9f086d2faa96f90607a0c59d97ffe86a12e067f3
parent250df4353fca5426f50209db9982a69966bfe239 (diff)
downloadgcc-70c912cff7f00414cad5c3dee2ab969f7f4acf08.tar.gz
gcc/:
PR target/46084 * explow.c (allocate_dynamic_stack_space): If flag_split_stack, request enough additional space for alignment, and force alignment. testsuite/: * gcc.target/i386/pr46084.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166383 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/explow.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46084.c69
4 files changed, 92 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1678d050b77..34b3601e938 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-05 Ian Lance Taylor <iant@google.com>
+
+ PR target/46084
+ * explow.c (allocate_dynamic_stack_space): If flag_split_stack,
+ request enough additional space for alignment, and force
+ alignment.
+
2010-11-05 Kai Tietz <kai.tietz@onevision.com>
* config/i386/i386.c (legitimate_pic_address_disp_p):
diff --git a/gcc/explow.c b/gcc/explow.c
index a83c6e87388..1d809bc8426 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -1340,7 +1340,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
least it doesn't cause a stack overflow. */
if (flag_split_stack)
{
- rtx available_label, space, func;
+ rtx available_label, ask, space, func;
available_label = NULL_RTX;
@@ -1355,10 +1355,19 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
}
#endif
+ /* The __morestack_allocate_stack_space function will allocate
+ memory using malloc. We don't know that the alignment of the
+ memory returned by malloc will meet REQUIRED_ALIGN. Increase
+ SIZE to make sure we allocate enough space. */
+ ask = expand_binop (Pmode, add_optab, size,
+ GEN_INT (required_align / BITS_PER_UNIT - 1),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ must_align = true;
+
func = init_one_libfunc ("__morestack_allocate_stack_space");
space = emit_library_call_value (func, target, LCT_NORMAL, Pmode,
- 1, size, Pmode);
+ 1, ask, Pmode);
if (available_label == NULL_RTX)
return space;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bace48a419d..b2642c1dfc0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-05 Ian Lance Taylor <iant@google.com>
+
+ PR target/46084
+ * gcc.target/i386/pr46084.c: New test.
+
2010-11-05 Steve Ellcey <sje@cup.hp.com>
* lib/target-supports.exp (check_function_available): Use -fno-builtin.
diff --git a/gcc/testsuite/gcc.target/i386/pr46084.c b/gcc/testsuite/gcc.target/i386/pr46084.c
new file mode 100644
index 00000000000..88bcd1ca5e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr46084.c
@@ -0,0 +1,69 @@
+/* This test needs to use setrlimit to set the stack size, so it can
+ only run on Unix. */
+/* { dg-do run { target *-*-linux* *-*-solaris* *-*-darwin* } } */
+/* { dg-require-effective-target avx } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack -O2 -mavx" } */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+ from the stack. */
+static void use_buffer (char *buf, size_t) __attribute__ ((noinline));
+static void
+use_buffer (char *buf, size_t c)
+{
+ size_t i;
+
+ for (i = 0; i < c; ++i)
+ buf[i] = (char) i;
+}
+
+/* Each recursive call uses 10 * i bytes. We call it 1000 times,
+ using a total of 5,000,000 bytes. If -fsplit-stack is not working,
+ that will overflow our stack limit. */
+
+static void
+down1 (int i)
+{
+ char buf[10 * i];
+
+ if (i > 0)
+ {
+ use_buffer (buf, 10 * i);
+ down1 (i - 1);
+ }
+}
+
+/* Same thing, using alloca. */
+
+static void
+down2 (int i)
+{
+ char *buf = alloca (10 * i);
+
+ if (i > 0)
+ {
+ use_buffer (buf, 10 * i);
+ down2 (i - 1);
+ }
+}
+
+int
+main (void)
+{
+ struct rlimit r;
+
+ /* We set a stack limit because we are usually invoked via make, and
+ make sets the stack limit to be as large as possible. */
+ r.rlim_cur = 8192 * 1024;
+ r.rlim_max = 8192 * 1024;
+ if (setrlimit (RLIMIT_STACK, &r) != 0)
+ abort ();
+ down1 (1000);
+ down2 (1000);
+ return 0;
+}