James Y Knight via llvm-dev
2015-Oct-06 21:54 UTC
[llvm-dev] SRET consistency between declaration and call site
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>
Jonas Maebe via llvm-dev
2015-Oct-07 08:28 UTC
[llvm-dev] SRET consistency between declaration and call site
James Y Knight via llvm-dev wrote on Tue, 06 Oct 2015:> 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.It won't work on AArch64 either: it uses a fixed register to pass struct return addresses, which is not used for other parameters under any circumstances. Jonas
Joerg Sonnenberger via llvm-dev
2015-Oct-07 23:28 UTC
[llvm-dev] SRET consistency between declaration and call site
On Wed, Oct 07, 2015 at 10:28:59AM +0200, Jonas Maebe via llvm-dev wrote:> > James Y Knight via llvm-dev wrote on Tue, 06 Oct 2015: > > >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. > > It won't work on AArch64 either: it uses a fixed register to pass struct > return addresses, which is not used for other parameters under any > circumstances.That seems to make it a pretty good case for consider sret mandatory in general. Joerg