OSDN Git Service

gcc/:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Nov 2010 23:45:32 +0000 (23:45 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Nov 2010 23:45:32 +0000 (23:45 +0000)
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

gcc/ChangeLog
gcc/explow.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr46084.c [new file with mode: 0644]

index 1678d05..34b3601 100644 (file)
@@ -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):
index a83c6e8..1d809bc 100644 (file)
@@ -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;
index bace48a..b2642c1 100644 (file)
@@ -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 (file)
index 0000000..88bcd1c
--- /dev/null
@@ -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;
+}