<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi Andy, Philip, Filip, Eric and others,<div><br></div><div>I didn’t want to talk about patchpoints, because I don’t know much about them.</div><div><br></div><div>Let me comment some remarks regarding the current proposal though:</div><div><br></div><i><span style="background-color: rgb(255, 255, 255);">I do request the following changes:</span><br></i><div><div><span style="background-color: rgb(255, 255, 255);"><i>- Mark it clearly as experimental.</i></span></div></div><div><div><span style="background-color: rgb(255, 255, 255);">I agree.</span></div><div><span style="background-color: rgb(255, 255, 255);"><br></span></div></div><div><div><span style="background-color: rgb(255, 255, 255);"><i>- Either don't specify the value computed in the edge cases, or allow those values to be specified as constant arguments to the call.  This allows efficient lowering to x86's div instruction if you want to make use of the trapping semantics.</i></span></div></div><div><div><span style="background-color: rgb(255, 255, 255);">Actually, I don’t see much use of this. Frontends like Java and Go will still have to generate calls with explicit constant for the edge cases, making them equivalent to the currently proposed intrinsics.</span></div><div><span style="background-color: rgb(255, 255, 255);"><br></span></div><div><blockquote type="cite"></blockquote><i>Given:<br></i><blockquote type="cite"></blockquote><i>void foo(int[] a, int d) {<br></i><blockquote type="cite"></blockquote><i>  for i = 0....a.length {<br></i><blockquote type="cite"></blockquote><i>    a[i] = a[i]/d<br></i><blockquote type="cite"></blockquote><i>  }<br></i><blockquote type="cite"></blockquote><i>}<br></i><blockquote type="cite"></blockquote><i>I want:<br></i><blockquote type="cite"></blockquote><i>void foo(int[]a, int d) {<br></i><blockquote type="cite"></blockquote><i>  // A single check here, not one per iteration<br></i><blockquote type="cite"></blockquote><i>  if( a.length > 0 && d == 0 ) throw;<br></i><blockquote type="cite"></blockquote><i>  for i = 0...a.length {<br></i><blockquote type="cite"></blockquote><i>    // arguably, it might be better to split the loop for d == -1<br></i><blockquote type="cite"></blockquote><i>    if( a[i] == INT_MIN && d == -1 ) {<br></i><blockquote type="cite"></blockquote><i>       continue;<br></i><blockquote type="cite"></blockquote><i>    }<br></i><blockquote type="cite"></blockquote><i>    a[i] = x86_div(a[i], d);<br></i><blockquote type="cite"></blockquote><i>  }<br></i><div bgcolor="#FFFFFF" text="#000000"><i>}</i><br></div></div><div>I understand your concern about the checks on x86 - in this example it really might be useful to have explicit CFG to help LICM to hoist the check out of the loop. I suggest to address this concern by adding mechanism to lower the intrinsics early (as proposed by Andy as well). Along with that, we can try to teach loop optimizations to deal with the intrinsics, and maybe later we won’t need this early-lowering at all (but while it’s needed it’ll be there). Thus, at the beginning, when the optimizations know nothing about the intrinsics, we’ll just lower them early for some targets (x86) and keep until CGP for the others (ARM64). Also, that will allow us to compare performance with early lowering vs CGP lowering.</div><div><br></div><div>Does that sound reasonable?</div><div><br></div><div>Thanks,</div><div>Michael</div><div><br><div><div>On May 3, 2014, at 4:45 AM, Andrew Trick <<a href="mailto:atrick@apple.com">atrick@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div><br class="Apple-interchange-newline">On May 2, 2014, at 5:01 PM, Philip Reames <<a href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000"><br><div class="moz-cite-prefix">On 05/02/2014 04:46 PM, Andrew Trick wrote:<br></div><blockquote cite="mid:7C8EBA7E-C1D6-472D-B530-46B8E21A55C5@apple.com" type="cite"><br><div><div>On May 2, 2014, at 4:25 PM, Philip Reames <<a moz-do-not-send="true" href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">I'm still not happy with hiding the explicit control flow, but I can achieve the same effect as:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">if( div by zero ) throw</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">(r, o, d) = safe.div(a,b);</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">if( o ) {</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">  r = a;</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">}</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;">i.e. emit a separate guard branch for the interesting condition and not utilize the value from the safe div. <span class="Apple-converted-space"> </span></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"></blockquote><div><br></div>Oh, I was just assuming you would deopt on either div-by-zero or overflow in order to optimize the common case.</div><div><br></div><div>So, the point of safe.div is that you don’t need control flow in the IR except to indicate the throw.</div><div><br></div><div>(r, o, d) = safe.div(a,b)</div><div>if (d) { patchpoint(throw, state) }</div><div><br></div><div>You could also explicitly check div-by-zero but it would be harder to fold away that extra check during lowering.</div></blockquote>I think I may have worded this badly.  The motivation for the explicit guard is to enable LICM and other branch simplifications.  This point is completely separate from the choice to deopt or not. <span class="Apple-converted-space"> </span><br><br>Consider the example below.  This is specifically for x86 with it's trapping divide.  Assume I am not utilizing traps, but need to guard the divide to handle the two special cases.  The exact handling of the edge cases isn't really significant, but the guards must exist. <span class="Apple-converted-space"> </span><br></div></blockquote><div><br></div>Yes, I completely understand what you want. I would like to hoist runtime traps even more aggressively than what LLVM will do when the control flow is explicit, but that has nothing to do with safe.div. We’ll discuss it later in a patchpoint thread.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">The issue of loop unswitching came up earlier in the thread. All these options are good</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">- generate fully explicit control flow + sdiv</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div>- generate partially explicit control flow + safe.div</div><div>- expand safe.div early based on TTI</div><div>- teach unswitching about safe.div</div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">The only thing I did not particularly like was the need for frontends to generate target specific intrinsics for a common operation.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">-Andy</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">Given:<br>void foo(int[] a, int d) {<br>  for i = 0....a.length {<br>    a[i] = a[i]/d<br>  }<br>}<br><br>I want:<br>void foo(int[]a, int d) {<br>  // A single check here, not one per iteration<br>  if( a.length > 0 && d == 0 ) throw;<br>  for i = 0...a.length {<br>    // arguably, it might be better to split the loop for d == -1<br>    if( a[i] == INT_MIN && d == -1 ) {<br>       continue;<br>    }<br>    a[i] = x86_div(a[i], d);<br>  }<br>}<br><br>Not:<br>void foo(int[]a, int d) {<br><br>  for i = 0...a.length {<br>    if( a[i] == INT_MIN && d == -1 ) {<br>       continue;<br>    }<br>    if( d == 0 ) throw;<br>    a[i] = x86_div(a[i], d);<br>  }<br>}<br><br>Hopefully, this helps clarify my point. <span class="Apple-converted-space"> </span><br><br>Philip</div></blockquote></div></blockquote></div><br></div></div></body></html>