[swift-evolution] [Pitch] Remove bit shift traps

Patrick Pijnappel patrickpijnappel at gmail.com
Fri Mar 18 01:58:57 CDT 2016


>
> 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.


That's unfortunate. Well at least we not *increasing* the amount of
branches by implementing the behavior. Because I'd argue that from the
user's perspective not trapping would be more sensible.

On Fri, Mar 18, 2016 at 5:05 PM, Greg Parker <gparker at apple.com> wrote:

>
> On Mar 17, 2016, at 10:34 PM, Patrick Pijnappel via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Currently, bit shifting with an amount greater than or equal to the size
> of the type traps:
>
> func foo(x: Int32) {
>   let y = x << 32 // Runtime trap (for any << or >> with amount >= 32)
> }
>
> I propose to make this not trap, and just end up with 0 (or ~0 in case of
> right-shifting a negative number):
>
>    - 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.
>    - If the intention is to make it analogous with
>    multiplication/division by 2**n, the checks don'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. Int.max << 1 doesn't
>    trap)
>    - It could lead to bugs where users expect this to work, e.g. the
>    following crashes when the entire buffer is consumed: buffer = buffer
>    << bitsConsumed
>    - Bitshift are often used in performance-sensitive code, and with the
>    current behavior any non-constant bit shift introduces a branch.
>
>
> 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.
>
>
> --
> Greg Parker     gparker at apple.com     Runtime Wrangler
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160318/f5a4e665/attachment.html>


More information about the swift-evolution mailing list