]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/37009 (No need to align stack when incoming stack is aligned)
authorH.J. Lu <hjl@gcc.gnu.org>
Wed, 6 Aug 2008 15:29:37 +0000 (08:29 -0700)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 6 Aug 2008 15:29:37 +0000 (08:29 -0700)
gcc/

2008-08-06  H.J. Lu  <hongjiu.lu@intel.com>

PR middle-end/37009
* cfgexpand.c (expand_stack_alignment): Check parm_stack_boundary
for incoming stack boundary.

* function.c (assign_parm_find_entry_rtl): Update
parm_stack_boundary.

* function.h (rtl_data): Add parm_stack_boundary.

* config/i386/i386.c (ix86_finalize_stack_realign_flags): Check
parm_stack_boundary for incoming stack boundary.

gcc/testsuite/

2008-08-06  H.J. Lu  <hongjiu.lu@intel.com>

PR middle-end/37009
* gcc.dg/torture/stackalign/alloca-2.c: New.
* gcc.dg/torture/stackalign/alloca-3.c: Likewise.
* gcc.dg/torture/stackalign/alloca-4.c: Likewise.
* gcc.dg/torture/stackalign/vararg-3.c: Likewise.
* gcc.target/i386/incoming-1.c: Likewise.
* gcc.target/i386/incoming-2.c: Likewise.
* gcc.target/i386/incoming-3.c: Likewise.
* gcc.target/i386/incoming-4.c: Likewise.
* gcc.target/i386/incoming-5.c: Likewise.

From-SVN: r138806

15 files changed:
gcc/ChangeLog
gcc/cfgexpand.c
gcc/config/i386/i386.c
gcc/function.c
gcc/function.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/incoming-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/incoming-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/incoming-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/incoming-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/incoming-5.c [new file with mode: 0644]

index 1e40f07e4f9daa20b389420f113d58eb157d9f8e..a22491f20e07f31d53fdeb5f1335a8e04232b5f0 100644 (file)
@@ -1,3 +1,17 @@
+2008-08-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR middle-end/37009
+       * cfgexpand.c (expand_stack_alignment): Check parm_stack_boundary
+       for incoming stack boundary.
+
+       * function.c (assign_parm_find_entry_rtl): Update
+       parm_stack_boundary.
+
+       * function.h (rtl_data): Add parm_stack_boundary.
+
+       * config/i386/i386.c (ix86_finalize_stack_realign_flags): Check
+       parm_stack_boundary for incoming stack boundary.
+
 2008-08-06  Joseph Myers  <joseph@codesourcery.com>
 
        * jump.c (rtx_renumbered_equal_p): Do not call subreg_regno_offset
index a943eff6ec1d25c154785e50f1778a77dd294730..8d1e5d2e3e827a6816bd48e9babf0c70fd023067 100644 (file)
@@ -2184,7 +2184,7 @@ static void
 expand_stack_alignment (void)
 {
   rtx drap_rtx;
-  unsigned int preferred_stack_boundary;
+  unsigned int preferred_stack_boundary, incoming_stack_boundary;
 
   if (! SUPPORTS_STACK_ALIGNMENT)
     return;
@@ -2215,8 +2215,15 @@ expand_stack_alignment (void)
   if (preferred_stack_boundary > crtl->stack_alignment_needed)
     crtl->stack_alignment_needed = preferred_stack_boundary;
 
+  /* The incoming stack frame has to be aligned at least at
+     parm_stack_boundary.  */
+  if (crtl->parm_stack_boundary > INCOMING_STACK_BOUNDARY)
+    incoming_stack_boundary = crtl->parm_stack_boundary;
+  else
+    incoming_stack_boundary = INCOMING_STACK_BOUNDARY;
+
   crtl->stack_realign_needed
-    = INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated;
+    = incoming_stack_boundary < crtl->stack_alignment_estimated;
   crtl->stack_realign_tried = crtl->stack_realign_needed;
 
   crtl->stack_realign_processed = true;
index d31f176d9a3b36c4ccdd9decef51eb19faddce05..7cd6211054788040bdee2c8a7820bdff4432bc18 100644 (file)
@@ -7614,7 +7614,10 @@ ix86_finalize_stack_realign_flags (void)
 {
   /* Check if stack realign is really needed after reload, and 
      stores result in cfun */
-  unsigned int stack_realign = (ix86_incoming_stack_boundary
+  unsigned int incoming_stack_boundary
+    = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
+       ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
+  unsigned int stack_realign = (incoming_stack_boundary
                                < (current_function_is_leaf
                                   ? crtl->max_used_stack_slot_alignment
                                   : crtl->stack_alignment_needed));
index 637775160ebefa2422c699a3a8f6a95f8fd13ccf..73600220c1507071c1b01deac0523a4a8d6975bc 100644 (file)
@@ -2261,6 +2261,11 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
                       entry_parm ? data->partial : 0, current_function_decl,
                       &all->stack_args_size, &data->locate);
 
+  /* Update parm_stack_boundary if this parameter is passed in the
+     stack.  */
+  if (!in_regs && crtl->parm_stack_boundary < data->locate.boundary)
+    crtl->parm_stack_boundary = data->locate.boundary;
+
   /* Adjust offsets to include the pretend args.  */
   pretend_bytes = all->extra_pretend_bytes - pretend_bytes;
   data->locate.slot_offset.constant += pretend_bytes;
index 1153fb0b4c4ea8a6f0e08a6657034e65f75ea923..eb85e3c37af964f8a1778ea53925a24dd9792d58 100644 (file)
@@ -339,6 +339,9 @@ struct rtl_data GTY(())
      to call other functions.  */
   unsigned int preferred_stack_boundary;
 
+  /* The minimum alignment of parameter stack.  */
+  unsigned int parm_stack_boundary;
+
   /* The largest alignment of slot allocated on the stack.  */
   unsigned int max_used_stack_slot_alignment;
 
index 1e035f3bf935f99a19df1d0ee1f55b312f3f97e1..ead96385f803049f6928b4ddc22c14410c301447 100644 (file)
@@ -1,4 +1,18 @@
+2008-08-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR middle-end/37009
+       * gcc.dg/torture/stackalign/alloca-2.c: New.
+       * gcc.dg/torture/stackalign/alloca-3.c: Likewise.
+       * gcc.dg/torture/stackalign/alloca-4.c: Likewise.
+       * gcc.dg/torture/stackalign/vararg-3.c: Likewise.
+       * gcc.target/i386/incoming-1.c: Likewise.
+       * gcc.target/i386/incoming-2.c: Likewise.
+       * gcc.target/i386/incoming-3.c: Likewise.
+       * gcc.target/i386/incoming-4.c: Likewise.
+       * gcc.target/i386/incoming-5.c: Likewise.
+
 2008-08-06  Aldy Hernandez  <aldyh@redhat.com>
+
        PR middle-end/35432
        * gcc.c-torture/compile/pr35432.c: New file.
 
@@ -9,7 +23,7 @@
 
 2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>
 
-       * gcc.c-torture/compile/20080806-1.c: New testcase.
+       * gcc.c-torture/compile/20080806-1.c: New testcase.
 
 2008-08-06  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c
new file mode 100644 (file)
index 0000000..b52dcf0
--- /dev/null
@@ -0,0 +1,56 @@
+/* PR middle-end/37009 */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-msse2" } */
+
+#include <emmintrin.h>
+#include "cpuid.h"
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      16
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+__attribute__ ((noinline))
+foo (__m128 x, __m128 y ,__m128 z , int size)
+{
+  char *p = __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main (void)
+{
+  __m128 x = { 1.0 };
+  unsigned int eax, ebx, ecx, edx;
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  /* Run SSE2 test only if host has SSE2 support.  */
+  if (edx & bit_SSE2)
+    foo (x, x, x, 5);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c
new file mode 100644 (file)
index 0000000..47f3607
--- /dev/null
@@ -0,0 +1,56 @@
+/* PR middle-end/37009 */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-msse2" } */
+
+#include <emmintrin.h>
+#include "cpuid.h"
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      16
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+__attribute__ ((noinline))
+foo (__m128 x, __m128 y ,__m128 z ,__m128 a, int size)
+{
+  char *p = __builtin_alloca (size + 1);
+  aligned i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+}
+
+int
+main (void)
+{
+  __m128 x = { 1.0 };
+  unsigned int eax, ebx, ecx, edx;
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  /* Run SSE2 test only if host has SSE2 support.  */
+  if (edx & bit_SSE2)
+    foo (x, x, x, x, 5);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c
new file mode 100644 (file)
index 0000000..0ff0d02
--- /dev/null
@@ -0,0 +1,41 @@
+/* PR middle-end/37009 */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-m32 -mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
+
+#include "check.h"
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+void
+__attribute__ ((noinline))
+foo (double x, double y ,double z ,double a, int size)
+{
+  char *p = __builtin_alloca (size + 1);
+  double i;
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+     abort ();
+    }
+
+  check (&i, __alignof__(i));
+}
+
+int
+main (void)
+{
+  double x =  1.0 ;
+  foo (x, x, x, x, 5);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c
new file mode 100644 (file)
index 0000000..cac2064
--- /dev/null
@@ -0,0 +1,84 @@
+/* PR middle-end/37009 */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-msse2" } */
+
+#include <stdarg.h>
+#include <emmintrin.h>
+#include "cpuid.h"
+#include "check.h"
+
+#ifndef ALIGNMENT
+#define ALIGNMENT      16
+#endif
+
+typedef int aligned __attribute__((aligned(ALIGNMENT)));
+
+void
+bar (char *p, int size)
+{
+  __builtin_strncpy (p, "good", size);
+}
+
+__m128 a = { 1.0 };
+
+void
+test (va_list arg)
+{
+  char *p;
+  aligned i;
+  int size;
+  double x;
+  __m128 e;
+
+  size = va_arg (arg, int);
+  if (size != 5)
+    abort ();
+
+  p = __builtin_alloca (size + 1);
+
+  x = va_arg (arg, double);
+  if (x != 5.0)
+    abort ();
+
+  bar (p, size);
+  if (__builtin_strncmp (p, "good", size) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+      abort ();
+    }
+
+  if (check_int (&i,  __alignof__(i)) != i)
+    abort ();
+
+  e = va_arg (arg, __m128);
+  if (__builtin_memcmp (&e, &a, sizeof (e)))
+    abort ();
+}
+
+void
+foo (const char *fmt, ...)
+{
+  va_list arg;
+  va_start (arg, fmt);
+  test (arg);
+  va_end (arg);
+}
+
+int
+main (void)
+{
+  __m128 x = { 1.0 };
+  unsigned int eax, ebx, ecx, edx;
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  /* Run SSE2 test only if host has SSE2 support.  */
+  if (edx & bit_SSE2)
+    foo ("foo", 5, 5.0, x);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/incoming-1.c b/gcc/testsuite/gcc.target/i386/incoming-1.c
new file mode 100644 (file)
index 0000000..fcc80f1
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/37009 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" } */
+
+#include <emmintrin.h>
+
+extern void bar (int *);
+
+int
+foo(__m128 x, __m128 y, __m128 z, int size)
+{
+  int __attribute((aligned(16))) xxx;
+
+  xxx = 2;
+  bar (&xxx);
+  return size;
+}
+
+/* { dg-final { scan-assembler "andl\[\\t \]*\\$-16,\[\\t \]*%esp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/incoming-2.c b/gcc/testsuite/gcc.target/i386/incoming-2.c
new file mode 100644 (file)
index 0000000..cc6c393
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/37009 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" } */
+
+#include <emmintrin.h>
+
+extern void bar (int *);
+
+int
+foo(__m128 x, __m128 y, __m128 z, __m128 a, int size)
+{
+  int __attribute((aligned(16))) xxx;
+
+  xxx = 2;
+  bar (&xxx);
+  return size;
+}
+
+/* { dg-final { scan-assembler-not "and\[l\]\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/incoming-3.c b/gcc/testsuite/gcc.target/i386/incoming-3.c
new file mode 100644 (file)
index 0000000..aad38b5
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/37009 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" } */
+
+#include <emmintrin.h>
+
+extern void bar (int *);
+
+int
+foo(__m128 y, int size, ...)
+{
+  int __attribute((aligned(16))) xxx;
+
+  xxx = 2;
+  bar (&xxx);
+  return size;
+}
+
+/* { dg-final { scan-assembler-not "and\[l\]\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/incoming-4.c b/gcc/testsuite/gcc.target/i386/incoming-4.c
new file mode 100644 (file)
index 0000000..270024b
--- /dev/null
@@ -0,0 +1,20 @@
+/* PR middle-end/37009 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" } */
+
+#include <stdarg.h>
+#include <emmintrin.h>
+
+extern void bar (int *);
+
+__m128
+foo(va_list arg) 
+{
+  int __attribute((aligned(16))) xxx;
+
+  xxx = 2;
+  bar (&xxx);
+  return va_arg (arg, __m128);
+}
+
+/* { dg-final { scan-assembler "andl\[\\t \]*\\$-16,\[\\t \]*%esp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/incoming-5.c b/gcc/testsuite/gcc.target/i386/incoming-5.c
new file mode 100644 (file)
index 0000000..38620bf
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR middle-end/37009 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-m32 -mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
+
+extern void bar (double *);
+
+double
+foo(double x)
+{
+  double xxx = x + 13.0;
+
+  bar (&xxx);
+  return xxx;
+}
+
+/* { dg-final { scan-assembler "andl\[\\t \]*\\$-8,\[\\t \]*%esp" } } */