<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 17, 2014 at 1:22 PM, Nick Lewycky <span dir="ltr"><<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On 17 October 2014 13:00, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Fri, Oct 17, 2014 at 12:56 PM, Nick Lewycky <span dir="ltr"><<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On 17 October 2014 12:17, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">In fact this was PR7272.<br></blockquote><div><br></div></span><div>PR7272 is the other way around?</div><div><br></div><div><div>define void @foo(i32* %x) {</div><div>  tail call void @bar(i32* byval %x)  ;; bad tail from PR7272</div><div>  ret void</div><div>}</div></div><div><br></div><div><div><div>define void @foo(i32* byval %x) {</div><div>  tail call void @bar(i32* %x)  ;; okay tail from this patch</div><div>  ret void</div><div>}</div></div></div></div></div></div></blockquote><div><br></div></span><div>This is precisely the case when it's not safe to tail call. You're capturing the address of something allocated on the current stack frame and passing it down, which you can't do.</div></div></div></div></blockquote><div><br></div></span><div>Maybe I'm misunderstanding, but I really think this is fine. Specifically I claim your error is on the clause "allocated on the current stack frame". It's not allocated on the current stack frame, it's allocated on the stack frame one above us.</div></div></div></div></blockquote><div><br></div><div>This is just the classic ambiguity of "who's frame are the arguments in?" 'byval' lets you capture the address of your arguments, sometimes. That argument stack space is reused to set up the arguments to the next call. Suppose that TCE did occur in the example you give, you would see this code for foo on regular x86, which has no register parameters:</div><div><br></div><div>foo:</div><div>  pushl ebp</div><div>  leal 8(%esp), %eax ; take address of x</div><div>  movl %eax, 8(%esp) ; store address of x into argument slot for tail call<br></div><div>  popl ebp</div><div>  jmp bar</div><div> </div><div>And now we've overwritten the contents of x.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>declare void @bar(i32*)<br></div><div><span class=""><div><br></div><div>define void @foo(i32* byval %x) {</div></span><div>  call void @bar(i32* %x)</div><div>  ret void</div><div>}</div><div><br></div><div>define void @test(i32* %y) {</div><div>  call void @foo(i32* byval %y)</div><div>  ret void</div><div>}</div></div><div><br></div><div><div>foo:                                    # @foo</div><div>        pushq   %rax<br></div><div>        leaq    16(%rsp), %rdi<br></div><div>        callq   bar</div><div>        popq    %rax</div><div>        retq</div></div><div><br></div><div><div>test:                                   # @test</div><div>        pushq   %rax<br></div><div>        movl    (%rdi), %eax<br></div><div>        movl    %eax, (%rsp)</div><div>        callq   foo</div><div>        popq    %rax</div><div>        retq</div></div></div></div></div></blockquote></div></div></div>