re PR middle-end/24306 (va_arg gets confused when skipping over certain zero-sized types with -msse)

2005-12-20  Richard Guenther  <rguenther@suse.de>

	PR middle-end/24306
	* builtins.c (std_gimplify_va_arg_expr): Do not align
	va frame for zero sized types.
	* config/i386/i386.c (ix86_gimplify_va_arg): Likewise.

        * gcc.target/i386/pr24306.c: New testcase.

From-SVN: r108854
This commit is contained in:
Richard Guenther 2005-12-20 16:20:27 +00:00 committed by Richard Biener
parent 338b5886ea
commit f5a7da0f62
5 changed files with 48 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2005-12-20 Richard Guenther <rguenther@suse.de>
PR middle-end/24306
* builtins.c (std_gimplify_va_arg_expr): Do not align
va frame for zero sized types.
* config/i386/i386.c (ix86_gimplify_va_arg): Likewise.
2005-12-20 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25501

View File

@ -4162,7 +4162,8 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
/* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
requires greater alignment, we must perform dynamic alignment. */
if (boundary > align)
if (boundary > align
&& !integer_zerop (TYPE_SIZE (type)))
{
t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,

View File

@ -4074,7 +4074,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
/* ... otherwise out of the overflow area. */
/* Care for on-stack alignment if needed. */
if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64)
if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64
|| integer_zerop (TYPE_SIZE (type)))
t = ovf;
else
{

View File

@ -1,3 +1,8 @@
2005-12-20 Richard Guenther <rguenther@suse.de>
PR middle-end/24306
* gcc.target/i386/pr24306.c: New testcase.
2005-12-20 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25501

View File

@ -0,0 +1,32 @@
/* { dg-do run } */
/* { dg-options "-msse" } */
extern void abort(void);
typedef int __attribute__ ((vector_size (16))) foo_t;
struct s
{
foo_t f[0];
} s1;
void
check (int x, ...) __attribute__((noinline));
void
check (int x, ...)
{
int y;
__builtin_va_list ap;
__builtin_va_start (ap, x);
__builtin_va_arg (ap, struct s);
y = __builtin_va_arg (ap, int);
if (y != 7)
abort ();
}
int main()
{
check (3, s1, 7);
return 0;
}