This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: va-arg-25.c still fails on i686-linux
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Geoffrey Keating <geoffk at apple dot com>
- Cc: Zack Weinberg <zack at codesourcery dot com>, gcc at gcc dot gnu dot org,gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Tue, 13 Jan 2004 01:22:01 +0100
- Subject: Re: va-arg-25.c still fails on i686-linux
- References: <871xq8p9is.fsf@codesourcery.com> <B555C890-452E-11D8-94EA-000A95B1F520@apple.com>
>
> On 09/01/2004, at 11:06 PM, Zack Weinberg wrote:
>
> >
> >I am still seeing va-arg-25.c fail at all optimization levels on
> >i686-linux. It has done so, as far as I can tell, ever since it
> >was introduced. Could you please either fix it or XFAIL it?
> >
> I think it would be better if an x86 port maintainer looked at this
> failure. The testcase does not fail on powerpc-Darwin.
It don't even need x86 port maintainer :)
The problem is wrong aligning of va_arg inside builtins.c when argument
alignment exceeds PARM_BOUNDARY.
Additionally I noticed some problems with SSE enabled (we mistakely used
SSE regiser for variadic call and output warning)
Note that I am not quite sure about the PAD_VARARGS_DOWN check, it just
seems appropriate at that place.
Bootstrapping/regtesting in progress, OK if it passes?
* builtins.c (std_expand_builtin_va_arg): Align operand when needed.
* i386.c (init_cumulative_args): Set warn_sse; fix handling of variadic
functions accepting SSE arguments
(function_arg): Warn only when asked to warn.
* i386.h (ix86_args): Add warn_sse/warn_mmx fiels.
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.270
diff -c -3 -p -r1.270 builtins.c
*** builtins.c 6 Jan 2004 16:51:08 -0000 1.270
--- builtins.c 13 Jan 2004 00:12:13 -0000
*************** std_expand_builtin_va_arg (tree valist,
*** 3990,3999 ****
--- 3990,4017 ----
tree align, alignm1;
tree rounded_size;
rtx addr;
+ HOST_WIDE_INT boundary;
/* Compute the rounded size of the type. */
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
+ boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+ if (boundary > PARM_BOUNDARY)
+ {
+ if (!PAD_VARARGS_DOWN)
+ {
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (PLUS_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.633
diff -c -3 -p -r1.633 i386.c
*** config/i386/i386.c 9 Jan 2004 02:31:40 -0000 1.633
--- config/i386/i386.c 13 Jan 2004 00:12:52 -0000
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1839,1844 ****
--- 1839,1846 ----
cum->nregs = ix86_regparm;
cum->sse_nregs = SSE_REGPARM_MAX;
cum->mmx_nregs = MMX_REGPARM_MAX;
+ cum->warn_sse = true;
+ cum->warn_mmx = true;
cum->maybe_vaarg = false;
/* Use ecx and edx registers if function has fastcall attribute */
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1857,1863 ****
are no variable arguments. If there are variable arguments, then
we won't pass anything in registers */
! if (cum->nregs)
{
for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
param != 0; param = next_param)
--- 1859,1865 ----
are no variable arguments. If there are variable arguments, then
we won't pass anything in registers */
! if (cum->nregs || !TARGET_MMX || !TARGET_SSE)
{
for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
param != 0; param = next_param)
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1868,1873 ****
--- 1870,1879 ----
if (!TARGET_64BIT)
{
cum->nregs = 0;
+ cum->sse_nregs = 0;
+ cum->mmx_nregs = 0;
+ cum->warn_sse = 0;
+ cum->warn_mmx = 0;
cum->fastcall = 0;
}
cum->maybe_vaarg = true;
*************** function_arg (CUMULATIVE_ARGS *cum, /* c
*** 2581,2587 ****
case V2DFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
! if (!TARGET_SSE && !warnedmmx)
{
warnedsse = true;
warning ("SSE vector argument without SSE enabled "
--- 2587,2593 ----
case V2DFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
! if (!TARGET_SSE && !warnedmmx && cum->warn_sse)
{
warnedsse = true;
warning ("SSE vector argument without SSE enabled "
*************** function_arg (CUMULATIVE_ARGS *cum, /* c
*** 2597,2603 ****
case V2SFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
! if (!TARGET_MMX && !warnedmmx)
{
warnedmmx = true;
warning ("MMX vector argument without MMX enabled "
--- 2603,2609 ----
case V2SFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
! if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
{
warnedmmx = true;
warning ("MMX vector argument without MMX enabled "
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.367
diff -c -3 -p -r1.367 i386.h
*** config/i386/i386.h 6 Jan 2004 10:49:56 -0000 1.367
--- config/i386/i386.h 13 Jan 2004 00:13:03 -0000
*************** typedef struct ix86_args {
*** 1743,1748 ****
--- 1743,1750 ----
int fastcall; /* fastcall calling convention is used */
int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
+ int warn_sse; /* True when we want to warn about SSE ABI. */
+ int warn_mmx; /* True when we want to warn about MMX ABI. */
int sse_regno; /* next available sse register number */
int mmx_words; /* # mmx words passed so far */
int mmx_nregs; /* # mmx registers available for passing */