[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-11-01 Thread jozefl.gcc at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #10 from Jozef Lawrynowicz  ---
(In reply to gnzlbg from comment #9)
> 
> @josef
> 
> > The MSP430 ABI is here: http://www.ti.com/lit/an/slaa534/slaa534.pdf
> Although confusingly that document is wrong regarding passing structures and
> unions by reference. As I mentioned before, structures and unions are always
> passed by reference, regardless of size.
> 
> Can you expand on this? That document says that aggregates smaller than
> 32-bit are passed in registers. We were trying to update our code
> documentation to cite the ABI specs and realized this. Do you have a link to
> where the current behavior is specified?

I think the ABI used to be correct regarding this, but then an optimization was
added to the TI compiler to always passes structures/unions by registers. At
least this is what I gleaned from searching the TI forums.

In the past TI also confirmed to me directly that that structs/unions should
always be passed by reference. I'll see if I can get them to update the ABI.

If you are curious about what any back-end is trying to do regarding
passing/returning by reference you could always check the implementation of
TARGET_PASS_BY_REFERENCE or TARGET_RETURN_IN_MEMORY.

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-31 Thread gonzalobg88 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #9 from gnzlbg  ---
> sparc is another, for example.  And or1k, too.

Yeah, I was wrong. x86/x64, arm32/64, aarch64, riscv, ppc64, mips64, ... are
some of the ABIs that do not have any of these issues because they special case
"all aggregates smaller than X", and that covers zero-sized types. 

Some ABIs (e.g. ppc32, MSP430) just say that all aggregates are passed by
reference, period.

And some ABIs (s390x, sparc as well I think), special case some sizes (e.g. 1,
2, 4, and 8 bytes wide aggregates), which means that 0 byte wide aggregates end
up being passed by reference instead.

---

@josef

> The MSP430 ABI is here: http://www.ti.com/lit/an/slaa534/slaa534.pdf
Although confusingly that document is wrong regarding passing structures and
unions by reference. As I mentioned before, structures and unions are always
passed by reference, regardless of size.

Can you expand on this? That document says that aggregates smaller than 32-bit
are passed in registers. We were trying to update our code documentation to
cite the ABI specs and realized this. Do you have a link to where the current
behavior is specified?

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-31 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #8 from Segher Boessenkool  ---
(In reply to gnzlbg from comment #7)
> > Note that the situation for zero-sized structs isn't very clear in
> > most ABIs, these included.
> 
> This is incorrect: zero-sized types are well-defined and efficient on most
> ABIs (most ABIs have a rule for small sizes, and these rules cover
> zero-sized types).

I don't agree that is true.  Besides, that is not what I said: a lot of
documentation is less than clear on behaviour here (certainly not for older
systems, where you *cannot* have zero-sized arguments in any case!)  So your
de-facto ABI becomes what some popular implementation does.  And if you are
unlucky you end up with two or more conflicting implementations.

> AFAICT, these two (MSP430 and PPC32) are some of the very
> few ABIs in which zero-sized types waste one register and one instruction
> for no reason. 

sparc is another, for example.  And or1k, too.

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-31 Thread gonzalobg88 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

gnzlbg  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #7 from gnzlbg  ---
> Note that the situation for zero-sized structs isn't very clear in
most ABIs, these included.

This is incorrect: zero-sized types are well-defined and efficient on most ABIs
(most ABIs have a rule for small sizes, and these rules cover zero-sized
types). AFAICT, these two (MSP430 and PPC32) are some of the very few ABIs in
which zero-sized types waste one register and one instruction for no reason. 

> You must have an unusual program if this ever matters ;-)

This bug / question was spawned due to a PR that attempted to fix a bug in Rust
for these ABIs when zero-sized types are involved. Rust has first-class support
for ZSTs and they are widely used, so the unusual situation where this happens
is essentially "all Rust programs". While ZSTs are "free" on most ABIs, on
these particular two, the ABI spec does not cover them, making "what GCC does"
essentially the only documented behavior for these. Hence the question, is
wasting one register and one instruction for ZSTs on these platforms a GCC bug,
or part of the intended ABI for these? 

It appears that the answer is that this is intended: these ABIs always pass
structs and unions indirectly, even if they are zero-sized, and that just means
that a register and an instruction must be used when ZSTs are passed, even if
those registers will never be read by anything. These ABIs know about this and
find it an acceptable trade-off, so that's what Rust will do.

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

Segher Boessenkool  changed:

   What|Removed |Added

 CC||segher at gcc dot gnu.org

--- Comment #6 from Segher Boessenkool  ---
(In reply to Bill Schmidt from comment #5)
> For the 32-bit ELF ABI, all structs (regardless of size) are passed using a
> pointer allowing for call-by-value semantics.  This is the source of ZSTs
> requiring a register.  So it's clear there is an ABI that requires this
> behavior.  (Look for the Parameter Passing Register Selection Algorithm in
> https://github.com/ryanarn/powerabi/blob/master/chap3-elf32abi.sgml.)
> 
> The 64-bit ABIs (both ELF V1 and ELF V2) pass structures in registers, and
> the parameter passing algorithms won't assign registers for size-0
> aggregates.  This is intentional.

Yup.  And everything is identical between LE and BE on all these ABIs.

Note that the situation for zero-sized structs isn't very clear in
most ABIs, these included.  You must have an unusual program if this
ever matters ;-)

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread wschmidt at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #5 from Bill Schmidt  ---
For 32-bit big-endian PowerPC (using the 32-bit ELF ABI), the same code
generation is provided by GCC and Clang.  I.e., here's the code generation for
Clang with -O2 -m32 -mbig-endian, using 6.0.0-1ubuntu2:

id_foo: # @id_foo
.Lfunc_begin0:
# %bb.0:
mr 3, 4
blr

The ABI document used to be posted at power.org, which is defunct.  However,
the sources are available at github:

https://github.com/ryanarn/powerabi

For the 32-bit ELF ABI, all structs (regardless of size) are passed using a
pointer allowing for call-by-value semantics.  This is the source of ZSTs
requiring a register.  So it's clear there is an ABI that requires this
behavior.  (Look for the Parameter Passing Register Selection Algorithm in
https://github.com/ryanarn/powerabi/blob/master/chap3-elf32abi.sgml.)

The 64-bit ABIs (both ELF V1 and ELF V2) pass structures in registers, and the
parameter passing algorithms won't assign registers for size-0 aggregates. 
This is intentional.

I hope this is helpful!

Bill

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread gonzalobg88 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #4 from gnzlbg  ---
Thanks for chiming in. I see the value in having a simple ABI rule. I guess
what confuses me is that the address passed in the calling convention for that
struct will never be used for anything or dereferenced.

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread jozefl.gcc at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #3 from Jozef Lawrynowicz  ---
(In reply to gnzlbg from comment #2)
> > I can only speak for msp430, but there's no problem with that generated 
> > assembly. Structures and unions are always passed by reference.
> 
> I suppose that by this you mean that the current behavior is "by design", is
> that correct ?
> 
> If so, could you explain the rationale of this design or point me to the ABI
> specification document or rationale for it ?

I was just considering from an MSP430 point of view, that if the struct can
have an address (it looks like it can, even though it has zero size), then that
assembly is correct. I'm afraid I don't have any specific insight into how GCC 
generically handles zero sized structs beyond that though.

The MSP430 ABI is here: http://www.ti.com/lit/an/slaa534/slaa534.pdf
Although confusingly that document is wrong regarding passing structures and
unions by reference. As I mentioned before, structures and unions are always
passed by reference, regardless of size.

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread gonzalobg88 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

--- Comment #2 from gnzlbg  ---
> I can only speak for msp430, but there's no problem with that generated 
> assembly. Structures and unions are always passed by reference.

I suppose that by this you mean that the current behavior is "by design", is
that correct ?

If so, could you explain the rationale of this design or point me to the ABI
specification document or rationale for it ?

[Bug target/92287] Mismatches in the calling convention for zero sized types

2019-10-30 Thread jozefl.gcc at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92287

Jozef Lawrynowicz  changed:

   What|Removed |Added

 CC||jozefl.gcc at gmail dot com

--- Comment #1 from Jozef Lawrynowicz  ---
I can only speak for msp430, but there's no problem with that generated
assembly. Structures and unions are always passed by reference.

R12:R15 are the argument registers, and the return value starts in R12.