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

Patrick Pijnappel patrickpijnappel at gmail.com
Fri Mar 18 05:17:39 CDT 2016


Actually this would increase code size, as you'd need to deal with the
negative case separately :/.

On Fri, Mar 18, 2016 at 5:58 PM, Patrick Pijnappel <
patrickpijnappel at gmail.com> wrote:

> 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/02f638e1/attachment.html>


More information about the swift-evolution mailing list