diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 15:29:37 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 15:29:37 +0000 |
commit | c6586120c02f926744ae783db4ce6401e0279d9a (patch) | |
tree | c3135360ae4b38adaeeb7da6a53d15035ce4a458 | |
parent | 62e423241b25fe595c15c14cb3e5f6434a037f48 (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 11 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc/function.c | 5 | ||||
-rw-r--r-- | gcc/function.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c | 84 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/incoming-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/incoming-2.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/incoming-3.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/incoming-4.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/incoming-5.c | 16 |
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" } } */ |