diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-05 23:45:32 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-05 23:45:32 +0000 |
commit | 70c912cff7f00414cad5c3dee2ab969f7f4acf08 (patch) | |
tree | 9f086d2faa96f90607a0c59d97ffe86a12e067f3 | |
parent | 250df4353fca5426f50209db9982a69966bfe239 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/explow.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr46084.c | 69 |
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; +} |