[Bug target/92287] Mismatches in the calling convention for zero sized types
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
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
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
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
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
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
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
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
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
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.