I’ve got around to calling external C functions and I noticed that
passing structs requires a special set of rules to comply with the C ABI.The first example is pretty clear that structs under a certain size
(sizeof pointer?) are demoted to an int, but what is happening in the
second example?Is there a guide that explains what this is and how to conform,
otherwise I have no chance at getting it right by guessing.
Congratulations, you have just discovered one of the long-standing known
issues with LLVM: implementing the C ABI correctly requires a “secret
handshake” between the frontend and the backend. (@nikic even used this
as an example of a known deficiency in LLVM in his keynote presentation
at the most recent LLVM Developers’ Meeting).
Unfortunately, there is at present no document for how to map a C ABI
function to LLVM function signature. The rules for mapping the C ABI to
assembly semantics is generally given in some ABI document. For
Unix-like systems, this is generally called the “SysV processor
supplement” or “SysV ABI”. As you seem to be looking for the x86-64 ABI,
the most up-to-date version of that may be found at
x86 psABIs / x86-64 psABI · GitLab. Do note that other OSes, in
particular Windows, will have a different ABI convention.
While it’s not actually documented, there is an explicit requirement
that for every backend, passing pointers and pointer-sized integers as
LLVM parameters (and returning them as the result) conforms to the C ABI
for returning such types. As a practical matter, you can generally
assume that i8, i16, and i32 should also work (although you may need a
zeroext/sext attribute to indicate signedness assumptions), as well as
any floating-point or vector type that is actually supported by the
hardware (note that this may be sensitive to function-specific hardware
features!). But using odd integer sizes, or larger-than-pointer integer
sizes (e.g., i7 or i128) should not be expected to work the same way,
and you can generally expect that LLVM struct parameters will not
conform to the C ABI.