<div dir="ltr">IE:<div><br></div><div>int *A;</div><div>int *D;</div><div><br></div><div>int bar()</div><div>{<br>  *D = 5; </div><div>if (im_bored)</div><div> throw();</div><div>return *D;</div><div><br></div><div><br></div><div>}</div><div><br></div><div>void foo()<br>{<br>int z = 0;</div><div><br></div><div>if (?)<br></div><div>{</div><div>  z = *A + 5;</div><div>}</div><div>bar()</div><div>y = *A + 5;</div><div><br></div><div>}</div><div><br></div><div>or whatever.</div><div>bar will be noalias of *A, but still validly throws, and is even read-write.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 15, 2016 at 6:26 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>The call does not have to be read only, it just has to no alias the load being pre'd.</span><div>The call may in fact be read/ write of some other memory<div><div class="h5"><br><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 15, 2016, 5:32 PM Andrew Trick <<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Jul 15, 2016, at 5:24 PM, Daniel Berlin <<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>> wrote:</div><br><div><blockquote class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br>LLVM's design decision is one where everything has to explicitly care about implicit early exits to get correct answers (and not to harp too much, but "not everything does", years later).  If they don't, they will get wrong answers.</div><div><br></div></div></div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">So, ironically, while looking at this, i noticed it turns out LLVM's PRE in GVN is another place that does not do this correctly either.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">It will insert and hoist loads past may-throw calls depending on whether it thinks the call aliases the pointer or not (IE depending on what memdep tells it, and memdep only cares about aliasing here when coming up with deps), regardless of whether the call is nounwind or not.  This is rare but can happen.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This is because memdep does this:<br>       // If the call has no effect on the queried pointer, just ignore it.<br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">So it does not give a dep, and PRE then never does anything else to check whether there is a may-throw call in the way of the hoist.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Testcase and patch coming.</div></div></blockquote></div><br></div><div style="word-wrap:break-word"><div>At some point I stopped thinking about this as a bug and realized that you just need to think of LLVM as modeling speculative code barriers as memory dependence. In LLVM, it makes no sense to have a readonly may-throw call.</div><div><br></div><div>Andy</div></div></blockquote></div></div></div></div></blockquote></div><br></div>