re PR middle-end/36859 (Caller/callee mismatch for vararg on stack)
authorH.J. Lu <hongjiu.lu@intel.com>
Fri, 18 Jul 2008 15:48:04 +0000 (15:48 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Fri, 18 Jul 2008 15:48:04 +0000 (08:48 -0700)
gcc/

2008-07-18  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-18  H.J. Lu  <hongjiu.lu@intel.com>

PR middle-end/36859
* gcc.target/i386/vararg-2.c: New.

From-SVN: r137955

gcc/ChangeLog
gcc/builtins.c
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/vararg-2.c [new file with mode: 0644]

index 0ff9b00..3c535ef 100644 (file)
@@ -1,5 +1,12 @@
 2008-07-18  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.
+
+2008-07-18  H.J. Lu  <hongjiu.lu@intel.com>
+
        PR middle-end/36858
        * function.c (locate_and_pad_parm): Cap boundary earlier.
 
index 60caa81..89eca00 100644 (file)
@@ -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);
index b63deb8..d910bd2 100644 (file)
@@ -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);
index 7cc31e8..cdf587a 100644 (file)
@@ -1,5 +1,10 @@
 2008-07-18  H.J. Lu  <hongjiu.lu@intel.com>
 
+       PR middle-end/36859
+       * gcc.target/i386/vararg-2.c: New.
+
+2008-07-18  H.J. Lu  <hongjiu.lu@intel.com>
+
        PR middle-end/36858
        * gcc.target/i386/vararg-1.c: New.
 
diff --git a/gcc/testsuite/gcc.target/i386/vararg-2.c b/gcc/testsuite/gcc.target/i386/vararg-2.c
new file mode 100644 (file)
index 0000000..0534ac7
--- /dev/null
@@ -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 <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 ();
+}