This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR middle-end/36859: Caller/callee mismatch for vararg on stack
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 16 Jul 2008 22:24:19 -0700
- Subject: PATCH: PR middle-end/36859: Caller/callee mismatch for vararg on stack
locate_and_pad_parm limits alignment of parameter on stack for callers
to PREFERRED_STACK_BOUNDARY. But std_gimplify_va_arg_expr tries to
align stack for callee without checking if the parameter alignment
is greater than PREFERRED_STACK_BOUNDARY. This patch fixes it. The
testcase won't run due to
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36858
which is fixed by
http://gcc.gnu.org/ml/gcc-patches/2008-07/msg01241.html
H.J.
----
gcc/
2008-07-16 H.J. Lu <hongjiu.lu@intel.com>
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-16 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/36859
* gcc.target/i386/vararg-2.c: New.
--- gcc/builtins.c.callee 2008-07-16 15:21:09.000000000 -0700
+++ gcc/builtins.c 2008-07-16 18:11:34.000000000 -0700
@@ -4775,7 +4775,15 @@ std_gimplify_va_arg_expr (tree valist, t
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);
+
+ /* Caller tries to align parameter on stack. If a parameter
+ alignment beyond PREFERRED_STACK_BOUNDARY, it will be aligned at
+ PREFERRED_STACK_BOUNDARY. */
+ 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);
--- gcc/config/i386/i386.c.callee 2008-07-16 15:21:13.000000000 -0700
+++ gcc/config/i386/i386.c 2008-07-16 15:22:52.000000000 -0700
@@ -5511,6 +5511,7 @@ ix86_gimplify_va_arg (tree valist, tree
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,20 @@ ix86_gimplify_va_arg (tree valist, tree
/* ... otherwise out of the overflow area. */
+ /* Caller tries to align parameter on stack. If a parameter
+ alignment beyond PREFERRED_STACK_BOUNDARY, it will be aligned at
+ PREFERRED_STACK_BOUNDARY. */
+ 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);
--- gcc/testsuite/gcc.target/i386/vararg-2.c.callee 2008-07-16 18:12:03.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/vararg-2.c 2008-07-16 18:08:08.000000000 -0700
@@ -0,0 +1,40 @@
+/* PR middle-end/36858 */
+/* { dg-do run } */
+/* { dg-options "-w" { target { lp64 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */
+
+#include "sse2-check.h"
+#include <stdarg.h>
+#include <emmintrin.h>
+
+__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 ();
+}