summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 15:29:37 +0000
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 15:29:37 +0000
commitc6586120c02f926744ae783db4ce6401e0279d9a (patch)
treec3135360ae4b38adaeeb7da6a53d15035ce4a458
parent62e423241b25fe595c15c14cb3e5f6434a037f48 (diff)
downloadgcc-c6586120c02f926744ae783db4ce6401e0279d9a.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138806 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/cfgexpand.c11
-rw-r--r--gcc/config/i386/i386.c5
-rw-r--r--gcc/function.c5
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/testsuite/ChangeLog16
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c56
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c56
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c41
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c84
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-1.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-2.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-3.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-4.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/incoming-5.c16
15 files changed, 380 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1e40f07e4f9..a22491f20e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index a943eff6ec1..8d1e5d2e3e8 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d31f176d9a3..7cd62110547 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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));
diff --git a/gcc/function.c b/gcc/function.c
index 637775160eb..73600220c15 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
diff --git a/gcc/function.h b/gcc/function.h
index 1153fb0b4c4..eb85e3c37af 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e035f3bf93..ead96385f80 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..b52dcf06566
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c
@@ -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
index 00000000000..47f3607c2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c
@@ -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
index 00000000000..0ff0d02c43b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c
@@ -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
index 00000000000..cac206499ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c
@@ -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
index 00000000000..fcc80f1ec2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/incoming-1.c
@@ -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
index 00000000000..cc6c3934253
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/incoming-2.c
@@ -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
index 00000000000..aad38b53ab4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/incoming-3.c
@@ -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
index 00000000000..270024bc15c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/incoming-4.c
@@ -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
index 00000000000..38620bfc938
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/incoming-5.c
@@ -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" } } */