Summary: | [4.3/4.4 Regression] -mregparm and fn decls without arguments | ||
---|---|---|---|
Product: | gcc | Reporter: | Jakub Jelinek <jakub> |
Component: | target | Assignee: | Jakub Jelinek <jakub> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | gcc-bugs, hjl.tools, hubicka, simon |
Priority: | P3 | ||
Version: | 4.3.0 | ||
Target Milestone: | 4.3.1 | ||
Host: | Target: | i686-linux | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2008-04-23 13:59:59 | |
Bug Depends on: | |||
Bug Blocks: | 31666, 31681, 31989 |
Description
Jakub Jelinek
2008-04-22 16:10:08 UTC
*** Bug 36014 has been marked as a duplicate of this bug. *** Caused I believe by http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124835 likely together with http://gcc.gnu.org/ml/gcc-patches/2007-03/msg01511.html While in 4.2 functions with fntype without TYPE_ARG_TYPES (i.e. !prototype_p) nregs, etc. would be preserved and maybe_vaarg set to true only afterwards, in 4.3 it is set early and the calling convention is forced to stack. maybe_vaarg is only used in 2 places - in init_cumulative_args itself, in !TARGET_64BIT case only, and in function_arg_64 (i.e. TARGET_64BIT case only). If we want to restore 4.2 and earlier behavior (I think we have to), then one fix could be e.g. only set maybe_vaarg to true for !prototype_p (fntype) if TARGET_64BIT. - ? (!prototype_p (fntype) || stdarg_p (fntype)) + ? ((TARGET_64BIT && !prototype_p (fntype)) + || stdarg_p (fntype)) As K&R fn declaration (i.e. !prototype_p) followed by stdarg_p definition or prototype is diagnosed as an error by diagnose_arglist_conflict, I believe this is safe. (In reply to comment #2) > Caused I believe by http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124835 > likely together with http://gcc.gnu.org/ml/gcc-patches/2007-03/msg01511.html > While in 4.2 functions with fntype without TYPE_ARG_TYPES (i.e. !prototype_p) > nregs, etc. would be preserved and maybe_vaarg set to true only afterwards, > in 4.3 it is set early and the calling convention is forced to stack. > > maybe_vaarg is only used in 2 places - in init_cumulative_args itself, in > !TARGET_64BIT case only, and in function_arg_64 (i.e. TARGET_64BIT case only). > If we want to restore 4.2 and earlier behavior (I think we have to), then > one fix could be e.g. only set maybe_vaarg to true for !prototype_p (fntype) > if TARGET_64BIT. > - ? (!prototype_p (fntype) || stdarg_p (fntype)) > + ? ((TARGET_64BIT && !prototype_p (fntype)) > + || stdarg_p (fntype)) > > As K&R fn declaration (i.e. !prototype_p) followed by stdarg_p definition or > prototype is diagnosed as an error by diagnose_arglist_conflict, I believe this > is safe. > Can you give it a try on both Linux/ia32 and Linux/x86-64? 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. Subject: Bug 36015 Author: jakub Date: Thu Apr 24 06:59:55 2008 New Revision: 134621 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=134621 Log: PR target/36015 * config/i386/i386.c (init_cumulative_args): Don't pass anything in registers for -m32 only if stdarg_p (fntype). * gcc.dg/pr36015.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr36015.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.c trunk/gcc/testsuite/ChangeLog Subject: Bug 36015 Author: jakub Date: Thu Apr 24 07:03:38 2008 New Revision: 134622 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=134622 Log: PR target/36015 * config/i386/i386.c (init_cumulative_args): Don't pass anything in registers for -m32 only if stdarg_p (fntype). * gcc.dg/pr36015.c: New test. Added: branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr36015.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/config/i386/i386.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog Fixed. |