<div dir="ltr"><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"><span style="font-size:13px">Defining large shifts to 0 or ~0 does not improve performance on some architectures. The result of the i386 and x86_64 shift instruction is undefined for shift equal to or larger than the data size. The arm64 shift instruction shifts by (shift_value % data_size). If you want large shifts to return zero on architectures like these then you still need a branch.</span></blockquote><div><br></div><div>That&#39;s unfortunate. Well at least we not <i>increasing</i> the amount of branches by implementing the behavior. Because I&#39;d argue that from the user&#39;s perspective not trapping would be more sensible.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 18, 2016 at 5:05 PM, Greg Parker <span dir="ltr">&lt;<a href="mailto:gparker@apple.com" target="_blank">gparker@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><br><div><blockquote type="cite"><div>On Mar 17, 2016, at 10:34 PM, Patrick Pijnappel via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div dir="ltr">Currently, bit shifting with an amount greater than or equal to the size of the type traps:<div><br></div><div><font face="monospace, monospace">func foo(x: Int32) {</font></div><div><font face="monospace, monospace">  let y = x &lt;&lt; 32 // Runtime trap (for any &lt;&lt; or &gt;&gt; with amount &gt;= 32)</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">I propose to make this not trap, and just end up with 0 (or ~0 in case of right-shifting a negative number):</font></div><div><ul><li><font face="arial, helvetica, sans-serif">Unlike the traps for integer arithmetic and casts, it is obvious what a bitshift past the end does as fundamentally the behavior stays the same.</font></li><li><font face="arial, helvetica, sans-serif">If the intention is to make it analogous with multiplication/division by 2**n, the checks don&#39;t really change anything. Right shift are still identical to divisions by 2**n. Left shifts are like multiplication by 2**n but with different overflow behavior, which is already the case with the current rules (e.g. </font><font face="monospace, monospace">Int.max &lt;&lt; 1</font><font face="arial, helvetica, sans-serif"> doesn&#39;t trap)</font></li><li><font face="arial, helvetica, sans-serif">It could lead to bugs where users expect this to work, e.g. the following crashes when the entire buffer is consumed: </font><font face="monospace, monospace">buffer = buffer &lt;&lt; bitsConsumed</font></li><li><font face="arial, helvetica, sans-serif">Bitshift are often used in performance-sensitive code, and with the current behavior any non-constant bit shift introduces a branch.</font></li></ul></div></div></div></blockquote><br></div></div></div><div>Defining large shifts to 0 or ~0 does not improve performance on some architectures. The result of the i386 and x86_64 shift instruction is undefined for shift equal to or larger than the data size. The arm64 shift instruction shifts by (shift_value % data_size). If you want large shifts to return zero on architectures like these then you still need a branch.</div><span><font color="#888888"><div><br></div><div><br></div><div>-- </div><div>Greg Parker     <a href="mailto:gparker@apple.com" target="_blank">gparker@apple.com</a>     Runtime Wrangler</div><div><br></div><div><br></div></font></span></div></blockquote></div><br></div></div>