> On Mar 17, 2016, at 10:34 PM, Patrick Pijnappel via swift-evolution 
> <[email protected]> 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     [email protected] <mailto:[email protected]>     Runtime 
Wrangler


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to