<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 15, 2016 at 2:54 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Fri, Jul 15, 2016 at 2:44 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>Hi Daniel,<br>
<br>
Daniel Berlin wrote:<br></span><span>
>     Don't we have the same problems for "exit(0)"<br>
><br>
><br>
> This is a noreturn call, so yes, iit has another hidden control<br>
> flow-side-effect of a slightly different kind. GCC models it as an extra<br>
> fake edge from the BB containing a noreturn call to the exit block of<br>
> the function, so that nothing sinks below it by accident.<br>
<br></span>
Just to be clear, it'd have to keep that sort of edge for all call<br>
sites, unless it can prove that the call target does not call exit?</blockquote><div><br></div></span><div>Yes.</div><div><br></div><div><div>/* Add fake edges to the function exit for any non constant and non</div><div>    noreturn calls (or noreturn calls with EH/abnormal edges),</div><div>    volatile inline assembly in the bitmap of blocks specified by BLOCKS</div><div>    or to the whole CFG if BLOCKS is zero. </div><div>...</div><div><br></div><div>    The goal is to expose cases in which entering a basic block does</div><div>    not imply that all subsequent instructions must be executed.  */</div></div><span class=""><div><br></div></span></div></div></div></blockquote><div><br></div><div>Note that this is also necessary to makes post-dominance correct (but we already do it in most cases, but i think there are still bugs open about correctness)</div><div><br></div><div>For dominance, the dominance relationship for exit blocks a noreturn blocks reach also changes , though i don't honestly remember if it's material or not, and i'm a bit lazy to think about it.  But here's an example:<br><br></div><div><br></div><div>IE given</div><div><br></div><div>A (may-throw)</div><div>|</div><div>v</div><div>B</div><div>|</div><div>v</div><div>C (exit)</div><div><br></div><div><br></div><div>Here, we have A dominates B dominates C</div><div><br></div><div>So the dominator tree is</div><div>A</div><div>|</div><div>v</div><div>B</div><div>|</div><div>v</div><div>C</div><div><br></div><div>Now, if you add an edge from A to C, you have:<br><br></div><div>A dominates B</div><div>Neither B nor A dominate C (C's idom is somewhere above, so it's in a sibling tree somewhere).</div><div><br></div><div><div><br class="">IE</div><div><br></div><div>A    C</div><div> |    </div><div>B   </div></div><div><br></div><div><br></div><div>In GCC, there is a single exit block, and it is always empty (returns are connected to the exit block). </div><div>Thus, the above will not prevent an optimization that should otherwise happen, from happening.</div><div><br></div><div>Because LLVM's exit blocks contain real code, it may</div><div><br></div><div>You can actually get even worse (ie really wrong) situations if the "exit" blocks somehow have successors, but thankfully we don't have a case where that happens that i know :)<br><br></div><div><br></div></div></div></div>