diff options
author | Ian Lance Taylor <iant@google.com> | 2010-11-05 23:45:32 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2010-11-05 23:45:32 +0000 |
commit | c3928dde21846d4572238317390613c8bcb042b6 (patch) | |
tree | 9f086d2faa96f90607a0c59d97ffe86a12e067f3 /gcc | |
parent | 037de943dc054e19f7387c56668fbb6375bee268 (diff) | |
download | gcc-c3928dde21846d4572238317390613c8bcb042b6.zip gcc-c3928dde21846d4572238317390613c8bcb042b6.tar.gz gcc-c3928dde21846d4572238317390613c8bcb042b6.tar.bz2 |
re PR target/46084 (gcc.dg/split-4.c failed with -mavx -m32)
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.
From-SVN: r166383
Diffstat (limited to 'gcc')
-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 1678d05..34b3601 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 a83c6e8..1d809bc 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 bace48a..b2642c1 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 0000000..88bcd1c --- /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; +} |