re PR middle-end/37009 (No need to align stack when incoming stack is aligned)
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
This commit is contained in:
parent
e088f04bdb
commit
e94a448f66
15 changed files with 380 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
56
gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c
Normal file
56
gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c
Normal file
|
@ -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;
|
||||
}
|
56
gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c
Normal file
56
gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c
Normal file
|
@ -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;
|
||||
}
|
41
gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c
Normal file
41
gcc/testsuite/gcc.dg/torture/stackalign/alloca-4.c
Normal file
|
@ -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;
|
||||
}
|
84
gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c
Normal file
84
gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c
Normal file
|
@ -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;
|
||||
}
|
19
gcc/testsuite/gcc.target/i386/incoming-1.c
Normal file
19
gcc/testsuite/gcc.target/i386/incoming-1.c
Normal file
|
@ -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" } } */
|
19
gcc/testsuite/gcc.target/i386/incoming-2.c
Normal file
19
gcc/testsuite/gcc.target/i386/incoming-2.c
Normal file
|
@ -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\]" } } */
|
19
gcc/testsuite/gcc.target/i386/incoming-3.c
Normal file
19
gcc/testsuite/gcc.target/i386/incoming-3.c
Normal file
|
@ -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\]" } } */
|
20
gcc/testsuite/gcc.target/i386/incoming-4.c
Normal file
20
gcc/testsuite/gcc.target/i386/incoming-4.c
Normal file
|
@ -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" } } */
|
16
gcc/testsuite/gcc.target/i386/incoming-5.c
Normal file
16
gcc/testsuite/gcc.target/i386/incoming-5.c
Normal file
|
@ -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" } } */
|
Loading…
Add table
Reference in a new issue