<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Yes, it seems like WinEHPrepare should always be able to move landing pad code to somewhere appropriate.  Even if there's some involved code to handle the cases
 that force #1, it's great that the complexity is contained in WinEHPrepare.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I'm still confused about the apparent lack of constraints after WinEHPrepare. 
<b>Can we simply require/assume that WinEHPrepare be run after any passes that may move/insert code into landing pads?  Is that documented somewhere?</b><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">For a concrete example, consider your snippet showing what the IR would look like after outlining with #3.  What's to stop a later pass from redoing the hoist?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Thanks<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">-Joseph<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif"">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif""> Reid Kleckner [mailto:rnk@google.com]
<br>
<b>Sent:</b> Thursday, February 12, 2015 6:10 PM<br>
<b>To:</b> Joseph Tremoulet<br>
<b>Cc:</b> Kaylor, Andrew; Bataev, Alexey; Reid Kleckner (reid@kleckner.net); LLVM Developers Mailing List<br>
<b>Subject:</b> Re: [LLVMdev] RFC: Native Windows C++ exception handling<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<p class="MsoNormal">You're right, we would hoist the add to someplace before the notional indirectbr, but that needs to work anyway. After looking more closely at the IR, we would probably hoist into the landingpad instead of into the entry block. Here's the
 IR I have in my head after optimization and hoisting but before outlining:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">define i32 @foo(i32 %a, i32 %b) {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">entry:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  invoke void @maybe_throw()<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      to label %ret unwind label %lpad<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">ret:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 0 ; The return case<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">lpad:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %ehvals = landingpad { i8*, i32 } personality ...<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      catch ... ; typeinfo for int<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      catch ... ; typeinfo for float<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %sum = add i32 %a, %b   ; hoisted out from catch_int and catch_float via CSE or something<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ... ; dispatch on the selector, effectively doing a switch<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">catch_int:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 %sum<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">catch_float:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %s1 = add i32 %sum, 1<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 %s1<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">... ; resume<o:p></o:p></p>
</div>
<p class="MsoNormal">}<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">We have a couple options during EH preparation:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">1. Outline the add into a cleanup, store the result into the frameallocation, and access it in the catch handler<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">2. Sink the add back into the handlers, which we can do because it has no side effects (better)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">3. Sink the add past the catch handlers and past the notional indirectbr into the blocks referenced by the handler return result<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Number 3 is probably the best, and it would look like:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">define i8* @int_handler(i8*, i8*) {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i8* basicblockaddr(@func, %catch_int)<br>
}<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">define i8* @float_handler(i8*, i8*) {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i8* basicblockaddr(@func, %catch_float)<br>
}<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">define i32 @foo(i32 %a, i32 %b) {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">entry:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  invoke void @maybe_throw()<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      to label %ret unwind label %lpad<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">ret:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 0 ; The return case<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">lpad:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %ehvals = landingpad { i8*, i32 } personality ...<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      catch ... ; typeinfo for int<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      catch ... ; typeinfo for float<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %rejoin_at = call i8* @llvm.eh.actions(... @int_handler, ... @float_handler, ...)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  indirectbr i8* %rejoin_at, [ label %catch_int, label %catch_float ]<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">catch_int:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %s1 = add i32 %a, %b<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 %s1<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">catch_float:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %s2 = add i32 %a, %b<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  %s3 = add i32 %s2, 1<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ret i32 %s3<o:p></o:p></p>
</div>
<p class="MsoNormal">}<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">But even if we aren't smart enough to do #3, which could implement #1 by additional outlining. It's ugly though. =/<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">In practice, I don't think this situation will occur very often because the catch blocks look like this:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">catch_int:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  call void @llvm.eh.begincatch(i8* %ehptr)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ... ; user code<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  call void @llvm.eh.endcatch()<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  ... ; rejoin normal control<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Anything we can hoist out of "user code" here can usually be sunk back in. If it's not trivial like a hoisted store to an unescaped internal global, then we'll have to emit something that looks like a destructor cleanup.<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">On Thu, Feb 12, 2015 at 7:43 AM, Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com" target="_blank">jotrem@microsoft.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">>
</span>We'd have to hoist a + b to somewhere that dominates L1 and L2. I think the only BB in your program that dominates is the entry block<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I don't follow.  What path do you see from entry to either L1 or L2 that doesn't pass through the
 indirectbr?  In order to reach either L1 or L2, the call to maybe_throw() must raise an exception (else we'd return 0 from foo), the exception must be caught by one of the two handlers (else we'd unwind out of foo), and one of the outlined handlers must have
 executed and returned.  Don't those conditions correspond to the path from entry to the indirectbr?</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">To clarify, I'm not trying to assert there's a problem; I'm new to LLVM and trying to understand
 the model.  I've worked before on a compiler that similarly used stand-in code to model control flow effected by the runtime/unwinder, and we had these issues with code motion.  Our system was closed enough that we could just have the affected optimizations
 check for the relevant opcodes (we were doing the equivalent of using a special exitlandingpad terminator instead of indirectbr) and avoid pushing code across them; I don't know if a similar approach is appropriate in LLVM, or if there is (or should be) a
 way to annotate the block to indicate that it's one of these cases and new code inserted there would get skipped over at run-time, or if it's ok to just assume that those sort of optimizations don't run after EH Preparation, or what.  Even if I am misunderstanding
 the shape of the flow graph in my example as you suggest, is there no cause for concern that some post-outlining pass might try to insert code into that block?  Like maybe some sort of late profile instrumentation?  It's great if there's not; I'm just trying
 to understand why not.</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Thanks</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">-Joseph</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a name="14b8006b1c678f53_14b7e75e23d9ebc5__MailE"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span></a><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif"">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri","sans-serif""> Reid Kleckner [mailto:<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>]
<br>
<b>Sent:</b> Wednesday, February 11, 2015 5:09 PM<br>
<b>To:</b> Joseph Tremoulet<br>
<b>Cc:</b> Kaylor, Andrew; Bataev, Alexey; Reid Kleckner (<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>); LLVM Developers Mailing List<br>
<b>Subject:</b> Re: [LLVMdev] RFC: Native Windows C++ exception handling</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">On Wed, Feb 11, 2015 at 1:57 PM, Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com" target="_blank">jotrem@microsoft.com</a>> wrote:<o:p></o:p></p>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723">Ah, ok.  So if the outliner sees non-dispatch code in the landing pad area, it can find/create somewhere
 to put it and an appropriate eh.actions annotation to get an EH table generated that will ensure it gets executed appropriately at run-time (in this example, perform the add before invoking either handler); is that more or less the idea?  That makes sense,
 thanks.</span><o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Yep. In the worst case, we could model code before landing pad dispatch as a cleanup handler, but I think the most common transforms are easily undone. Consider your example where
 a + b gets hoisted before the catch dispatch. Adds have no side effects, so we can freely sink them back down into the catch handler once we start outlining.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Things that are hard to move, like loads and stores to unknown memory locations, cannot be hoisted over the llvm.eh.begincatch() call in the first place. It should act as a memory
 barrier.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723"> </span><o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723">I have the same question about the post-outlining IR.  To change the example to one where the bait
 won't get outlined, suppose you had</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">int foo(int a, int b) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">  try {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    try {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">      maybe_throw();</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">      return 0;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    } catch (int) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">      // some code here that gets outlined</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    L1:</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    return a + b;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">  } catch (float) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">    // some other code here that also gets outlined</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">  }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">  L2:</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">  return (a + b) + 1;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Courier New";color:black">}</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723">and suppose that nothing gets moved around before outlining.  Then, after outlining, the landingpad
 will be followed by an eh.actions call and then an indirect branch that targets L1 and L2, correct?</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#385723">Do we need to worry that a late codesize optimization might want to merge the adds by hoisting them
 up above the indirect branch? If that happened, wouldn't it get skipped over if an exception were raised?</span><o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">We'd have to hoist a + b to somewhere that dominates L1 and L2. I think the only BB in your program that dominates is the entry block. In the IR, the fake 'indirectbr' instruction
 after the call to @llvm.eh.actions helps keep the CFG conservatively correct.<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</body>
</html>