From c565a1e7b774b3a578f15ca865e5eb69aebc0820 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 18 Jul 2008 15:48:04 +0000 Subject: [PATCH] re PR middle-end/36859 (Caller/callee mismatch for vararg on stack) gcc/ 2008-07-18 H.J. Lu PR middle-end/36859 * builtins.c (std_gimplify_va_arg_expr): Limit alignment to PREFERRED_STACK_BOUNDARY. * config/i386/i386.c (ix86_gimplify_va_arg): Likewise. testsuite/ 2008-07-18 H.J. Lu PR middle-end/36859 * gcc.target/i386/vararg-2.c: New. From-SVN: r137955 --- gcc/ChangeLog | 7 +++++ gcc/builtins.c | 11 ++++++- gcc/config/i386/i386.c | 13 ++++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/vararg-2.c | 40 ++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/vararg-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ff9b006c95..3c535ef5c4f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-07-18 H.J. Lu + + PR middle-end/36859 + * builtins.c (std_gimplify_va_arg_expr): Limit alignment to + PREFERRED_STACK_BOUNDARY. + * config/i386/i386.c (ix86_gimplify_va_arg): Likewise. + 2008-07-18 H.J. Lu PR middle-end/36858 diff --git a/gcc/builtins.c b/gcc/builtins.c index 60caa8126d8..89eca002270 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4775,7 +4775,16 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) type = build_pointer_type (type); align = PARM_BOUNDARY / BITS_PER_UNIT; - boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT; + boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); + + /* When we align parameter on stack for caller, if the parameter + alignment is beyond PREFERRED_STACK_BOUNDARY, it will be + aligned at PREFERRED_STACK_BOUNDARY. We will match callee + here with caller. */ + if (boundary > PREFERRED_STACK_BOUNDARY) + boundary = PREFERRED_STACK_BOUNDARY; + + boundary /= BITS_PER_UNIT; /* Hoist the valist value into a temporary for the moment. */ valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b63deb834bf..d910bd24250 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5511,6 +5511,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) int indirect_p = 0; tree ptrtype; enum machine_mode nat_mode; + int arg_boundary; /* Only 64bit target needs something special. */ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist))) @@ -5709,13 +5710,21 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) /* ... otherwise out of the overflow area. */ + /* When we align parameter on stack for caller, if the parameter + alignment is beyond PREFERRED_STACK_BOUNDARY, it will be + aligned at PREFERRED_STACK_BOUNDARY. We will match callee + here with caller. */ + arg_boundary = FUNCTION_ARG_BOUNDARY (VOIDmode, type); + if ((unsigned int) arg_boundary > PREFERRED_STACK_BOUNDARY) + arg_boundary = PREFERRED_STACK_BOUNDARY; + /* Care for on-stack alignment if needed. */ - if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64 + if (arg_boundary <= 64 || integer_zerop (TYPE_SIZE (type))) t = ovf; else { - HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8; + HOST_WIDE_INT align = arg_boundary / 8; t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), ovf, size_int (align - 1)); t = fold_convert (sizetype, t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7cc31e80f4e..cdf587a21ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-07-18 H.J. Lu + + PR middle-end/36859 + * gcc.target/i386/vararg-2.c: New. + 2008-07-18 H.J. Lu PR middle-end/36858 diff --git a/gcc/testsuite/gcc.target/i386/vararg-2.c b/gcc/testsuite/gcc.target/i386/vararg-2.c new file mode 100644 index 00000000000..0534ac77478 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vararg-2.c @@ -0,0 +1,40 @@ +/* PR middle-end/36859 */ +/* { dg-do run } */ +/* { dg-options "-w" { target { lp64 } } } */ +/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */ + +#include "sse2-check.h" +#include +#include + +__m128 +__attribute__((noinline)) +test (int a, ...) +{ + __m128 x; + va_list va_arglist; + + va_start (va_arglist, a); + x = va_arg (va_arglist, __m128); + va_end (va_arglist); + return x; +} + +__m128 n1 = { -283.3, -23.3, 213.4, 1119.03 }; + +int +__attribute__((noinline)) +foo (void) +{ + __m128 x = test (1, n1); + if (__builtin_memcmp (&x, &n1, sizeof (x)) != 0) + abort (); + return 0; +} + +static void +__attribute__((noinline)) +sse2_test (void) +{ + foo (); +} -- 2.30.2