Logic for representation of struct parameters and results


I know that frontends are generally responsible for lowering struct parameters and results to primitive types to ensure that they are passed/returned in the correct registers. However, I can't find any logic in the following:


Why is the parameter a "byval" while the return value is turned into an i32? Would it be wrong if our compiler also lowers the parameter into an i32? If not, could it nevertheless could cause problems in case code compiled by our compiler and compiled by clang is mixed via LTO? (suppose the tinyfunc is compiled with clang and that we import it with "declare i32 @tinyfunc (i32)")

In general, is there any documentation for how exactly frontends should lower aggregates to LLVM for the various architectures/ABIs/calling conventions? If not, are there at least any hints regarding when it is safe to assume that "byval" will do "the right thing"? We already support all calling conventions for our native code generators so I know which parameters have to be zero/sign-extended, in which registers or where on the stack they should be passed etc, but it's really not clear to me how this maps onto LLVM IR. Every time I think I've discovered some logic, I find a new exception like the above. Additionally, looking at clang's output may not even be the best approach, as it appears to still wrongly map certain things (e.g. a "struct { int a, b, c, d; }" is returned using an sret parameter instead of in rax/rdx on darwin/x86-64 when compiling with clang 3.3)

FWIW, all results are still the same with clang 3.4.