It appears that C functions which return structs sometimes use a magic hidden return argument carrying a pointer to some memory to be overwritten with the return value of the function.
For example, a C function declared like:
MyBuffer string_from_double(double d);
will appear in LLVM like:
declare void @string_from_double(%struct.MyBuffer* sret align 8, double)
Despite appearances, the function actually has two arguments instead of one. The magic argument is apparently identified by its sret
tag.
(Bewilderingly, LLVM doesn't automatically perform the transformation from return-by-value, even for cdecl
convention functions. There must be a reason for it, but it seems counterintuitive to me).
So my question is: From the compiler backend, how do I tell when an FFI function needs to be transformed into an "sret" form?