JuliaLang/julia — pull request #8933 by toivoh (2014-11-07 21:06:27+00:00)
Title: RFC: Avoid unwanted signed/unsigned conversion check in pointer + and -

After #8420, each use of `+(::Ptr,::Int)` and `-(::Ptr,::Int)` includes a (probably unintentional) check for illegal signed/unsigned conversion: (maybe also for other `Integer` subtypes)

julia> code_native(+, (Ptr{Int}, Int))
.text
Filename: pointer.jl
Source line: 65
push RBP
mov RBP, RSP
test RSI, RSI
Source line: 65
js 8
add RDI, RSI
mov RAX, RDI
pop RBP
ret
movabs RAX, 140346252604120
mov RDI, QWORD PTR [RAX]
movabs RAX, 140346237622048
mov ESI, 65
call RAX

I can only guess that this was not intended. Pointer arithmetic is inherently unsafe and impossible to check automatically, but it can be quite useful in tight hand-optimized loops, where the above check adds overhead and precludes further optimizations.

This patch brings back the previous, simple behavior:

julia> code_native(+, (Ptr{Int}, Int))
.text
Filename: pointer.jl
Source line: 65
push RBP
mov RBP, RSP
Source line: 65
lea RAX, QWORD PTR [RDI + RSI]
pop RBP
ret

I put RFC in the title to make sure that this is actually desirable to fix, and to get feedback on the way that I have fixed it:
* The new code assumes implicitly that a `UInt` has the same size as a `Ptr`. Afaik this is always the case in Julia, but should I rely on it?
* A new fix will be needed if we get checked arithmetic by default.

Btw, I noticed that `-(::Ptr,::Ptr)` gives an unsigned result. Might also be worth fixing?