public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct
@ 2005-01-21 16:07 gary at intrepid dot com
  2005-01-21 16:40 ` [Bug target/19566] " gary at intrepid dot com
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: gary at intrepid dot com @ 2005-01-21 16:07 UTC (permalink / raw)
  To: gcc-bugs

The x86_64 compiler (verified in gcc 3.4.3, configured for
x86_64-redhat-linux)
chooses a different parameter passing method when passing a struct value,
depending upon whether a contained 16 bit bit field is declared as either
an 'int' or a 'short int'.

Given the following test case:

--------------------

typedef struct shared_ptr_struct
  {
    unsigned long phase  : 48;
    unsigned int thread : 16;
    void *addr;
  } shared_ptr_t;

int y;
shared_ptr_t sp = {1, 2, &y};

int
get_thread (shared_ptr_t p)
{
  return p.thread;
}

int
main() {
  int t = get_thread (sp);
  return t;
}

--------------------

A value of this type will be passed in two registers:

typedef struct shared_ptr_struct
  {
    unsigned long phase  : 48;
    unsigned short thread : 16;
    void *addr;
  } shared_ptr_t;


        movq    sp(%rip), %rdi
        movq    sp+8(%rip), %rsi
        call    get_thread


but a value of this type will be passed on the stack:

typedef struct shared_ptr_struct
  {
    unsigned long phase  : 48;
    unsigned int thread  : 16;
    void *addr;
  } shared_ptr_t;

        movq    sp(%rip), %rax
        movq    %rax, (%rsp)
        movq    sp+8(%rip), %rax
        movq    %rax, 8(%rsp)
        call    get_thread

Is there anything about the ABI or C language definition
that dictates the difference in choice of parameter value passing method,
or should both struct definitions lead to the same choice of
parameter passing method?

Assuming these two declarations should pass a value of type shared_ptr_t
in the same fashion, I think the error originates in classify_argument in
config/i386/i386.c:

static int
classify_argument (enum machine_mode mode, tree type,
                   enum x86_64_reg_class classes[MAX_CLASSES], int
bit_offset)
{
  HOST_WIDE_INT bytes =
    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE
(mode);
  int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) /
UNITS_PER_WORD;

when the thread field is declared as 'short', the mode will be HImode.
However,
if thread is declared as type 'int', the mode will be SImode. In the 'int'
case
the value for bytes is 4, and the value for words is 2, because threads is
not
aligned on a 32 bit boundary. Eventually, the logic will return here:

      /* Misaligned fields are always returned in memory.  */
      if (bit_offset % mode_alignment)
        return 0;

which tells the caller that the type of interest must be passed in memory
(on the stack) rather than in a register.

It looks as if either classify_argument is using the wrong computation for
the value of 'bytes', or earlier in the declaration of the processing of
'threads' when declared as an 'int', the compiler should use the smallest
sized
integer type that will accommodate the field (ie, a short int).

Also posted to the gcc mailing list:
http://gcc.gnu.org/ml/gcc/2005-01/msg01221.html

-- 
           Summary: x86_64 - inconsistent choice of parameter passing method
                    for 16 byte struct
           Product: gcc
           Version: 3.4.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gary at intrepid dot com
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: x86_64-redhat-linux


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
  2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
@ 2005-01-21 16:40 ` gary at intrepid dot com
  2005-01-22  0:53 ` schlie at comcast dot net
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: gary at intrepid dot com @ 2005-01-21 16:40 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From gary at intrepid dot com  2005-01-21 16:40 -------
change from bug/c to bug/target

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c                           |target


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
  2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
  2005-01-21 16:40 ` [Bug target/19566] " gary at intrepid dot com
@ 2005-01-22  0:53 ` schlie at comcast dot net
  2005-01-30 20:18 ` pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: schlie at comcast dot net @ 2005-01-22  0:53 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From schlie at comcast dot net  2005-01-22 00:53 -------
just for reference, as didn't notice this pr eariler: http://gcc.gnu.org/ml/gcc/2005-01/msg01270.html


-- 


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
  2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
  2005-01-21 16:40 ` [Bug target/19566] " gary at intrepid dot com
  2005-01-22  0:53 ` schlie at comcast dot net
@ 2005-01-30 20:18 ` pinskia at gcc dot gnu dot org
  2005-01-30 21:34 ` gary at intrepid dot com
  2005-02-19 17:56 ` aj at gcc dot gnu dot org
  4 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-01-30 20:18 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-01-30 20:17 -------
I should note that these two structs are incompatible so why do you think they should be passed the 
same?

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ABI


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
  2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
                   ` (2 preceding siblings ...)
  2005-01-30 20:18 ` pinskia at gcc dot gnu dot org
@ 2005-01-30 21:34 ` gary at intrepid dot com
  2005-02-19 17:56 ` aj at gcc dot gnu dot org
  4 siblings, 0 replies; 10+ messages in thread
From: gary at intrepid dot com @ 2005-01-30 21:34 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From gary at intrepid dot com  2005-01-30 21:34 -------
>From a C point of view, the types are incompatible. But, from an ABI point of 
view, shouldn't values of both types be passed in the same way (ie, copied into 
registers rather than being copied to the stack in one case, and registers in 
the other)?

This problem arose when generating code for an experimental dialect of C, 
called UPC, where certain 'shared pointer' values are passed as a structure 
which includes a (phase, thread, address) triple, and phase is 48 bits, thread 
is 16 bits, and the address part of the value is 64 bits. The compiler 
(internally) chose a 'short' representation of thread, where the separately 
compiled runtime declared the thread field as an 'int'. (Clearly, there is a 
simple workaround, which is to declare the types identically.)

However, if we look at the differently declared types from an ABI point of 
view, they have the same internal rep. in terms of size and alignment, and I 
think that the ABI would say that values of both types should be passed in 
registers.  Certainly, the code inside 'classify_argument()' shouldn't view 
the 'short' field as being unaligned, which in turn causes the value of (64 
bit) words to be 2 rather 1.


-- 


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
  2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
                   ` (3 preceding siblings ...)
  2005-01-30 21:34 ` gary at intrepid dot com
@ 2005-02-19 17:56 ` aj at gcc dot gnu dot org
  4 siblings, 0 replies; 10+ messages in thread
From: aj at gcc dot gnu dot org @ 2005-02-19 17:56 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aj at gcc dot gnu dot org  2005-02-19 07:06 -------
Honza, could you look at this, please? 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |hubicka at gcc dot gnu dot
                   |dot org                     |org
             Status|UNCONFIRMED                 |ASSIGNED


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
       [not found] <bug-19566-9975@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2008-09-26 23:19 ` hjl dot tools at gmail dot com
@ 2008-09-27  0:19 ` gary at intrepid dot com
  3 siblings, 0 replies; 10+ messages in thread
From: gary at intrepid dot com @ 2008-09-27  0:19 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from gary at intrepid dot com  2008-09-27 00:18 -------
(In reply to comment #8)
> It has been fixed in gcc 4.1.2.

FWIW, I just tried this on a gcc 4.0.1 that we have on hand here, and it also
appeared to be fixed in that version.


-- 


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
       [not found] <bug-19566-9975@http.gcc.gnu.org/bugzilla/>
  2008-08-03 17:40 ` ubizjak at gmail dot com
  2008-09-26 22:57 ` hubicka at gcc dot gnu dot org
@ 2008-09-26 23:19 ` hjl dot tools at gmail dot com
  2008-09-27  0:19 ` gary at intrepid dot com
  3 siblings, 0 replies; 10+ messages in thread
From: hjl dot tools at gmail dot com @ 2008-09-26 23:19 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from hjl dot tools at gmail dot com  2008-09-26 23:18 -------
It has been fixed in gcc 4.1.2.


-- 

hjl dot tools at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |RESOLVED
         Resolution|                            |FIXED
   Target Milestone|---                         |4.1.2


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
       [not found] <bug-19566-9975@http.gcc.gnu.org/bugzilla/>
  2008-08-03 17:40 ` ubizjak at gmail dot com
@ 2008-09-26 22:57 ` hubicka at gcc dot gnu dot org
  2008-09-26 23:19 ` hjl dot tools at gmail dot com
  2008-09-27  0:19 ` gary at intrepid dot com
  3 siblings, 0 replies; 10+ messages in thread
From: hubicka at gcc dot gnu dot org @ 2008-09-26 22:57 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from hubicka at gcc dot gnu dot org  2008-09-26 22:56 -------
Hi,
so to be sure I didn't mess up anything.  The following is testcase I use:
typedef struct shared_ptr_struct
{
  unsigned long phase:48;
  unsigned int thread:16;
  void *addr;
} shared_ptr_t;


int y;
shared_ptr_t sp = { 1, 2, &y };

int
get_thread (shared_ptr_t p)
{
  return p.thread;
}

int
main ()
{
  int t = get_thread (sp);
  return t;
}

The following is assembly I get:
get_thread:
.LFB0:
        .cfi_startproc
        movq    %rdi, %rax
        shrq    $48, %rax
        ret
        .cfi_endproc
.LFE0:
        .size   get_thread, .-get_thread
        .p2align 4,,15
.globl main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        movq    sp(%rip), %rdi
        movq    sp+8(%rip), %rsi
        jmp     get_thread
        .cfi_endproc
.LFE1:

i.e. everything is passed in registers.  I get same code from GCC-4.1
get_thread:
.LFB2:
        movq    %rdi, -16(%rsp)
        movzwl  -10(%rsp), %eax
        ret
.LFE2:
        .size   get_thread, .-get_thread
        .p2align 4,,15
.globl main
        .type   main, @function
main:
.LFB3:
        movq    sp(%rip), %rdi
        movq    sp+8(%rip), %rsi
        jmp     get_thread
.LFE3:

THis is oldest GCC I have around.   I remember debugging this problem once
before, probably in different duplicate of this PR so I hope it is long fixed.


-- 

hubicka at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |WAITING


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


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

* [Bug target/19566] x86_64 - inconsistent choice of parameter passing method for 16 byte struct
       [not found] <bug-19566-9975@http.gcc.gnu.org/bugzilla/>
@ 2008-08-03 17:40 ` ubizjak at gmail dot com
  2008-09-26 22:57 ` hubicka at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: ubizjak at gmail dot com @ 2008-08-03 17:40 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from ubizjak at gmail dot com  2008-08-03 17:38 -------
Can we have a final word from ABI people here please?


-- 

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=19566


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

end of thread, other threads:[~2008-09-27  0:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-21 16:07 [Bug c/19566] New: x86_64 - inconsistent choice of parameter passing method for 16 byte struct gary at intrepid dot com
2005-01-21 16:40 ` [Bug target/19566] " gary at intrepid dot com
2005-01-22  0:53 ` schlie at comcast dot net
2005-01-30 20:18 ` pinskia at gcc dot gnu dot org
2005-01-30 21:34 ` gary at intrepid dot com
2005-02-19 17:56 ` aj at gcc dot gnu dot org
     [not found] <bug-19566-9975@http.gcc.gnu.org/bugzilla/>
2008-08-03 17:40 ` ubizjak at gmail dot com
2008-09-26 22:57 ` hubicka at gcc dot gnu dot org
2008-09-26 23:19 ` hjl dot tools at gmail dot com
2008-09-27  0:19 ` gary at intrepid 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).