------- Comment #4 from jakub at gcc dot gnu dot org 2008-04-23 13:29 ------- I've instead regtested: --- gcc/config/i386/i386.c.jj 2008-04-01 13:34:27.000000000 +0200 +++ gcc/config/i386/i386.c 2008-04-23 13:38:14.000000000 +0200 @@ -3501,7 +3501,7 @@ init_cumulative_args (CUMULATIVE_ARGS *c { /* If there are variable arguments, then we won't pass anything in registers in 32-bit mode. */ - if (cum->maybe_vaarg) + if (stdarg_p (fntype)) { cum->nregs = 0; cum->sse_nregs = 0;
patch (on i686 only, as this is !TARGET_64BIT hunk of code). IMHO it best matches what 4.2 and earlier did. Here is the 4.2 code: cum->maybe_vaarg = false; ... /* Determine if this function has variable arguments. This is indicated by the last argument being 'void_type_mode' if there are no variable arguments. If there are variable arguments, then we won't pass anything in registers in 32-bit mode. */ if (cum->nregs || cum->mmx_nregs || cum->sse_nregs) { for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; param != 0; param = next_param) { next_param = TREE_CHAIN (param); if (next_param == 0 && TREE_VALUE (param) != void_type_node) { 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->float_in_sse = 0; } cum->maybe_vaarg = true; } } } if ((!fntype && !libname) || (fntype && !TYPE_ARG_TYPES (fntype))) cum->maybe_vaarg = true; The param/next_param testing IMHO is stdarg_p test, so cum->nregs etc. are cleared only if !TARGET_64BIT && stdarg_p (fntype). maybe_vaarg is set if stdarg_p (fntype), or for fntype && !prototype_p (fntype), or for !fntype && !libname. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36015