[llvm-dev] SRET consistency between declaration and call site

James Y Knight via llvm-dev
Tue, 06 Oct 2015 21:54:58 -0000

On Oct 6, 2015, at 4:33 PM, Reid Kleckner via llvm-dev <llvm-dev at
lists.llvm.org> wrote:
> On Tue, Oct 6, 2015 at 1:21 PM, Joerg Sonnenberger via llvm-dev
<llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>
wrote:
> Can you give an example of where it would trigger in LTO and when should
> not?
>
> You could imagine that __muldc3 might be implemented in C, and it might be
implemented without using _Complex so that it can be compiled by a compiler
without _Complex support. Instead of using a _Complex double return type, it
would use a pointer outparam as the first parameter, and it would return that
pointer as usual in RAX. Yes, this is a prototype mismatch and probably UB
according to C, but this might be part of an implementation which knows
something about the platform lowering.
>
> Generally we try to make these sorts of things "work". For
example, if you pass parameters to a function pointer call and we later discover
the function takes no parameters, instcombine will discard the arguments rather
than making the call unreachable. IMO the same logic applies to ABI attributes
like sret.

Certainly a mismatch between sret and not-sret from caller to callee could not
possibly work on sparc, because sparc's calling convention for struct return
is totally bonkers.

If you're doing an sret return, you need to return to the call address +12,
instead of +8, because the instruction at the usual caller+8 return address is
expected to be a trap instruction.


Said trap also has the size of the struct encoded in it, and is there in order
that it can be inspected by the callee to verify that the size of the struct the
caller allocated is the same as what the callee expected. (Most impls don't
bother with said verification step, because, really, wtf is the point.)

So if the caller thinks it's calling a non-sret function, but it is actually
calling an sret function, it'll put code at +8, and the callee will skip
that. Conversely, if the caller thinks it's calling an sret function, and
the function is not actually, the function will return into the trap at +8. So,
sure, llvm doesn't actually need to detect this mismatch, but the generated
code is guaranteed to be busted if there is such a mismatch, so really nobody
should ever be doing that.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20151006/b498424f/attachment.html>