public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/41017]  New: regparm=3 passes structures inconsistently
@ 2009-08-09 18:36 mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-09 18:40 ` [Bug target/41017] " mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-09 18:36 UTC (permalink / raw)
  To: gcc-bugs

regparm=3 passes structures in registers if they fit there. There is
inconsistency in this rule, if structure contains only float or only double
type, it is passed on the stack.

Example:

__attribute__((regparm(3))) void function(struct s s);

now, the argument passing varies wildly depending on the definition of "struct
s".

struct s { float a; float b; } --- passed in registers
struct s { float a; } --- passed on stack
struct s { float a[1]; } --- passed on stack
struct s { float a[2]; } --- passed in registers
struct s { float a; int b; } --- passed in registers
struct s { float a[1]; float b[0]; } --- passed on stack
struct s { double a; } --- passed on stack
struct s { struct { float a; }; } --- passed on stack
union s { float a; } --- passed in registers
struct s { union { float a; }; } --- passed in registers
struct s { struct { float a; } q[1]; } --- passed on stack
struct s { long double a; } --- passed on stack
struct s { union { long double a; } } --- passed in registers

--- actually it seems that if the structure contains only one floating point
entry inside other structures or arrays (not unions), it is passed on stack,
not in registers ... otherwise it is passed in registers.

Hardly anyone deliberately designed it this way. Gcc internals are exposed to
the ABI! If the structure contains just one entry, its mode is different from
BLKmode and it takes different path in function_arg_advance_32 and
function_arg_32.

I'd propose to change it so that structures are always passed in registers, the
current state makes it hard or impossible to do any automatic marshalling of
arguments for regparm functions. I found this bug when trying to extend libffi
to handle regparm=3 calling convention.

(another way to fix this is to pass structures always on the stack, maybe it
would generate faster code, but it would create more ABI-incompatibility pain)


-- 
           Summary: regparm=3 passes structures inconsistently
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mikulas at artax dot karlin dot mff dot cuni dot cz
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-09 18:40 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-09 19:10 ` rguenth at gcc dot gnu dot org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-09 18:40 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from mikulas at artax dot karlin dot mff dot cuni dot cz  2009-08-09 18:40 -------
Created an attachment (id=18331)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18331&action=view)
a proposed patch. Fixed bug 41013 as well.

Change it so that all the aggregate types take common code path, so passing of
the structure no longer depends on its content.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-09 18:40 ` [Bug target/41017] " mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-09 19:10 ` rguenth at gcc dot gnu dot org
  2009-08-09 19:13 ` rguenth at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-08-09 19:10 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from rguenth at gcc dot gnu dot org  2009-08-09 19:10 -------
Can you check if regparm(3) behavior ever changed during the gcc releases?

> Hardly anyone deliberately designed it this way. Gcc internals are exposed to
> the ABI!

well, regparm(n) is certainly out of the psABI and I am not sure the regparm
ABI has a proper specification anywhere.  But indeed it is exposed as ABI so
we shouldn't change it if we didn't do so repeatedly in the past.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-09 18:40 ` [Bug target/41017] " mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-09 19:10 ` rguenth at gcc dot gnu dot org
@ 2009-08-09 19:13 ` rguenth at gcc dot gnu dot org
  2009-08-09 21:16 ` mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-08-09 19:13 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from rguenth at gcc dot gnu dot org  2009-08-09 19:13 -------
Btw, the documentation claims regparm only affects integral parameters.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (2 preceding siblings ...)
  2009-08-09 19:13 ` rguenth at gcc dot gnu dot org
@ 2009-08-09 21:16 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-10  8:05 ` ubizjak at gmail dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-09 21:16 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from mikulas at artax dot karlin dot mff dot cuni dot cz  2009-08-09 21:16 -------
Regparm changed between gcc 3.x -> 4.x (I remember it too painfully, I had to
rewrite some assembler files). In 3.x, all arguments were incrementing register
count, even if they were on stack, if you had (float f1, int i2, int i3), f1
was on stack, i2 was in EDX and i3 was in ECX. In 4.x it changed so that f1 is
on stack, i2 is in EAX and i3 is in EDX. Similarly, (double f1, int i2, int i3)
was (stack, ECX, stack) in 3.x and (stack, EAX, EDX) in 4.x.

If we change it so that structures are always in registers, it will be the
least painful thing, because they already are in registers almost always
(except few pathological cases, like struct containing only float or double).
So it won't likely hurt too much, because few programmers rely on regparm(3)
for external ABI, few programmers pass structures directly and few programmers
declare structure with only one member. And the programmer will be hurt only if
he does all these three things.

If you want to change it to be consistent with the documentation (not with
existing implementation) and pass structures always on stack, I wouldn't object
against it. Just don't change it later.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (3 preceding siblings ...)
  2009-08-09 21:16 ` mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-10  8:05 ` ubizjak at gmail dot com
  2009-08-10  8:06 ` ubizjak at gmail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: ubizjak at gmail dot com @ 2009-08-10  8:05 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from ubizjak at gmail dot com  2009-08-10 08:05 -------
(In reply to comment #4)

> If you want to change it to be consistent with the documentation (not with
> existing implementation) and pass structures always on stack, I wouldn't object
> against it. Just don't change it later.
> 

IMO, regparm ABI should be documented in i386 psABI first [1], so we will have
something to implement against. As it stands now, regparm is mainly internal to
gcc, so non-exported functions can be called more efficiently. So, everything
is OK as long as the caller and the callee agree on the location of arguments.

OTOH, if regparm is documented, we can implement alternative function entry
points, so exported functions will also benefit from regparm ABI. See how ICC
handles this.

[1] http://groups-beta.google.com/group/ia32-abi


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (4 preceding siblings ...)
  2009-08-10  8:05 ` ubizjak at gmail dot com
@ 2009-08-10  8:06 ` ubizjak at gmail dot com
  2009-08-10 19:37 ` mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: ubizjak at gmail dot com @ 2009-08-10  8:06 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from ubizjak at gmail dot com  2009-08-10 08:06 -------
Adding H.J. to CC.


-- 

ubizjak at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hjl dot tools at gmail dot
                   |                            |com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (5 preceding siblings ...)
  2009-08-10  8:06 ` ubizjak at gmail dot com
@ 2009-08-10 19:37 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-11 20:39 ` mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-10 19:37 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from mikulas at artax dot karlin dot mff dot cuni dot cz  2009-08-10 19:36 -------
Worse, try to return these structures with -freg-struct-return and it also
follows this inconsistent pattern, some are returned in EAX:EDX, some are
returned in ST(0).

It is even inconsistent between GCC releases:
struct {
        float a[1];
        float a[0];
}
is returned in EAX on GCC-3.3 and in ST(0) on GCC-3.4 and GCC-4.

It is much worse than regparm inconsistency because some operating systems (for
example FreeBSD) use -freg-struct-return as a default calling convention and
GCC generates incompatible code for them.

Where is this "-freg-struct-return" thing documented. The documentation in
manpage, "Return 'struct' and 'union' values in registers when possible." is
really inadequate.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (6 preceding siblings ...)
  2009-08-10 19:37 ` mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-11 20:39 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-11 20:41 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-18  4:49 ` hjl dot tools at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-11 20:39 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from mikulas at artax dot karlin dot mff dot cuni dot cz  2009-08-11 20:38 -------
Created an attachment (id=18341)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=18341&action=view)
A patch for -freg-struct-return

Another patch that makes -freg-struct-return consistent.
Return structures with size 1, 2, 4, 8 bytes in EAX or EDX:EAX. No matter what
they contain.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (7 preceding siblings ...)
  2009-08-11 20:39 ` mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-11 20:41 ` mikulas at artax dot karlin dot mff dot cuni dot cz
  2009-08-18  4:49 ` hjl dot tools at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: mikulas at artax dot karlin dot mff dot cuni dot cz @ 2009-08-11 20:41 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from mikulas at artax dot karlin dot mff dot cuni dot cz  2009-08-11 20:40 -------
The Basic rule implemented in both patches is: when you have aggregate type,
you MUST NOT look at mode to infer parameter or return method. It is
unreliable.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug target/41017] regparm=3 passes structures inconsistently
  2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
                   ` (8 preceding siblings ...)
  2009-08-11 20:41 ` mikulas at artax dot karlin dot mff dot cuni dot cz
@ 2009-08-18  4:49 ` hjl dot tools at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: hjl dot tools at gmail dot com @ 2009-08-18  4:49 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #10 from hjl dot tools at gmail dot com  2009-08-18 04:49 -------
(In reply to comment #3)
> Btw, the documentation claims regparm only affects integral parameters.
> 

Agreed, -regparm=N should only apply to integer parameters. I will take
a look when I find time.

BTW, -regparm=N is a gcc extension and out of psABI.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-08-18  4:49 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-09 18:36 [Bug target/41017] New: regparm=3 passes structures inconsistently mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-09 18:40 ` [Bug target/41017] " mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-09 19:10 ` rguenth at gcc dot gnu dot org
2009-08-09 19:13 ` rguenth at gcc dot gnu dot org
2009-08-09 21:16 ` mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-10  8:05 ` ubizjak at gmail dot com
2009-08-10  8:06 ` ubizjak at gmail dot com
2009-08-10 19:37 ` mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-11 20:39 ` mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-11 20:41 ` mikulas at artax dot karlin dot mff dot cuni dot cz
2009-08-18  4:49 ` hjl dot tools at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).