Bug 39496 - [4.3 Regression] GCC uses non-standard calling conventions for static functions with -O0.
Summary: [4.3 Regression] GCC uses non-standard calling conventions for static functio...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.3.4
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-03-18 21:10 UTC by Jim Blandy
Modified: 2009-04-22 15:02 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work: 3.3.6 4.3.4 4.4.0
Known to fail: 4.0.4 4.3.3
Last reconfirmed: 2009-03-18 21:32:10


Attachments
Test case (165 bytes, text/plain)
2009-03-18 21:11 UTC, Jim Blandy
Details
gcc44-pr39496.patch (1.04 KB, patch)
2009-03-19 07:58 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jim Blandy 2009-03-18 21:10:03 UTC
Even when compiling with -O0, GCC uses non-standard parameter passing conventions for static inline functions, which makes debugging difficult.

In this case, the function of interest converts a tagged value to a pointer; it's very helpful to be able to use this in GDB 'print' commands.

In the assembly code shown, notice that the function is expecting to find its argument in %eax, even though the standard IA-32 calling conventions pass the first argument on the stack.  The GDB session also demonstrates this.

$ (cd ~/gcc/gcc; svn info)
Path: .
URL: svn://gcc.gnu.org/svn/gcc/trunk
Repository Root: svn://gcc.gnu.org/svn/gcc
Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4
Revision: 144927
Node Kind: directory
Schedule: normal
Last Changed Author: gccadmin
Last Changed Rev: 144927
Last Changed Date: 2009-03-17 17:16:40 -0700 (Tue, 17 Mar 2009)

$ cat jsobj.i
extern "C"
{
  static inline struct JSObject *JSVAL_TO_OBJECT (int v)
  {
    return (struct JSObject *) (v & ~3);
  }
}
static int
obj_toSource (int *vp)
{
  JSVAL_TO_OBJECT (vp[0]);
}
int
main(int argc, char **argv)
{
}
$ c++ -v -O0 -g jsobj.i -o jsobj -save-temps
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/home/jimb/gcc --enable-languages=c,c++
Thread model: posix
gcc version 4.4.0 20090318 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic'
 /home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/cc1plus -fpreprocessed jsobj.i -quiet -dumpbase jsobj.i -mtune=generic -auxbase jsobj -g -O0 -version -o jsobj.s
GNU C++ (GCC) version 4.4.0 20090318 (experimental) (i686-pc-linux-gnu)
	compiled by GNU C version 4.4.0 20090318 (experimental), GMP version 4.2.2, MPFR version 2.3.2.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 00b593c3c99bbacc875575ff2b6655cc
COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic'
 as -V -Qy -o jsobj.o jsobj.s
GNU assembler version 2.18.93 (i486-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.18.93.20081009
COMPILER_PATH=/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/
LIBRARY_PATH=/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic'
 /home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o jsobj /usr/lib/crt1.o /usr/lib/crti.o /home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/crtbegin.o -L/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/../../.. jsobj.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/crtend.o /usr/lib/crtn.o
$ cat jsobj.s
...
JSVAL_TO_OBJECT:
.LFB0:
	.file 1 "jsobj.i"
	.loc 1 4 0
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	subl	$4, %esp
	movl	%eax, -4(%ebp)
	.loc 1 5 0
	movl	-4(%ebp), %eax
	andl	$-4, %eax
	.loc 1 6 0
	leave
	ret
...
$ gdb jsobj
GNU gdb (GDB) 6.8.50.20090106-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
(gdb) start
Temporary breakpoint 1 at 0x804844c: file jsobj.i, line 16.
Starting program: /home/jimb/mc/b/static-call/jsobj 

Temporary breakpoint 1, main (argc=1, argv=0xbffff8a4) at jsobj.i:16
16	}
Current language:  auto; currently c++
(gdb) set $eax = 0x42424242
(gdb) print JSVAL_TO_OBJECT(0x53535353)
$1 = (struct JSObject *) 0x42424240
(gdb) quit
The program is running.  Quit anyway (and kill it)? (y or n) y
$
Comment 1 Jim Blandy 2009-03-18 21:11:54 UTC
Created attachment 17490 [details]
Test case

This is the same test case used in the transcript; attached just for convenience.
Comment 2 Andrew Pinski 2009-03-18 21:14:13 UTC
"even though the standard IA-32 calling conventions pass the
first argument on the stack"

I thought this was disabled at -O0.  At -O1 this should be enabled.
Comment 3 Richard Biener 2009-03-18 21:32:10 UTC
Confirmed.  In 3.3 this worked (was probably not implemented).
Comment 4 Andrew Pinski 2009-03-18 21:56:03 UTC
  /* Use register calling convention for local functions when possible.  */
  if (decl && TREE_CODE (decl) == FUNCTION_DECL
      && !profile_flag)


That should include !optimize I think.
Comment 5 Andrew Pinski 2009-03-18 21:57:44 UTC
We used to check flag_unit_at_a_time in this function:
  /* Use register calling convention for local functions when possible.  */
  if (decl && TREE_CODE (decl) == FUNCTION_DECL
      && flag_unit_at_a_time && !profile_flag)

Which meant it never worked for C++ in 3.4 and above , for C, it always worked until 4.4 which removed the check.
Comment 6 Jakub Jelinek 2009-03-19 07:58:19 UTC
Created attachment 17491 [details]
gcc44-pr39496.patch

&& optimize, not !optimize.
Here is what I'm going to bootstrap/regtest.
Comment 7 Jakub Jelinek 2009-03-19 10:25:58 UTC
Subject: Bug 39496

Author: jakub
Date: Thu Mar 19 10:25:43 2009
New Revision: 144955

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144955
Log:
	PR target/39496
	* config/i386/i386.c (ix86_function_regparm): Don't optimize local
	functions using regparm calling conventions when not optimizing.
	(ix86_function_sseregparm): Similarly for sseregparm calling
	conventions.

	* gcc.target/i386/pr39496.c: New test.
	* g++.dg/other/pr39496.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/other/pr39496.C
    trunk/gcc/testsuite/gcc.target/i386/pr39496.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Jakub Jelinek 2009-03-19 12:02:04 UTC
Fixed on the trunk so far.
Comment 9 Jim Blandy 2009-03-19 19:51:28 UTC
Fixed for me in r144969.  Thank you all!
Comment 10 Joseph S. Myers 2009-03-31 21:11:40 UTC
Closing 4.2 branch.
Comment 11 Richard Biener 2009-04-22 13:29:57 UTC
This is worth fixing for 4.3.4.  I am testing a backport.
Comment 12 Richard Biener 2009-04-22 15:02:19 UTC
Fixed.
Comment 13 Richard Biener 2009-04-22 15:02:34 UTC
Subject: Bug 39496

Author: rguenth
Date: Wed Apr 22 15:01:45 2009
New Revision: 146583

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=146583
Log:
2009-04-22  Richard Guenther  <rguenther@suse.de>

        Backport from mainline:
        PR target/39496
        * config/i386/i386.c (ix86_function_regparm): Don't optimize local
        functions using regparm calling conventions when not optimizing.
        (ix86_function_sseregparm): Similarly for sseregparm calling
        conventions.

        * gcc.target/i386/pr39496.c: New test.
        * g++.dg/other/pr39496.C: New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/g++.dg/other/pr39496.C
      - copied unchanged from r144955, trunk/gcc/testsuite/g++.dg/other/pr39496.C
    branches/gcc-4_3-branch/gcc/testsuite/gcc.target/i386/pr39496.c
      - copied unchanged from r144955, trunk/gcc/testsuite/gcc.target/i386/pr39496.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