<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><div class="">On Oct 6, 2015, at 4:33 PM, Reid Kleckner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Oct 6, 2015 at 1:21 PM, Joerg Sonnenberger via llvm-dev <span dir="ltr" class=""><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Can you give an example of where it would trigger in LTO and when should<br class="">
not?</blockquote><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div></div></div></div></div></blockquote><br class=""></div><div>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.</div><div><br class=""></div><div>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.</div><div><br class=""></div><div><br class=""></div><div>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.)</div><div><br class=""></div><div>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.</div></body></html>