diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index e2773752c68e6..a3d110390b1d4 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -184,8 +184,6 @@ add_tfunc(sdiv_int, 2, 2, math_tfunc, 30) add_tfunc(udiv_int, 2, 2, math_tfunc, 30) add_tfunc(srem_int, 2, 2, math_tfunc, 30) add_tfunc(urem_int, 2, 2, math_tfunc, 30) -add_tfunc(add_ptr, 2, 2, math_tfunc, 1) -add_tfunc(sub_ptr, 2, 2, math_tfunc, 1) add_tfunc(neg_float, 1, 1, math_tfunc, 1) add_tfunc(add_float, 2, 2, math_tfunc, 1) add_tfunc(sub_float, 2, 2, math_tfunc, 1) @@ -664,6 +662,9 @@ function pointer_eltype(@nospecialize(ptr)) return Any end +@nospecs function pointerarith_tfunc(𝕃::AbstractLattice, ptr, offset) + return ptr +end @nospecs function pointerref_tfunc(𝕃::AbstractLattice, a, i, align) return pointer_eltype(a) end @@ -707,6 +708,8 @@ end end return ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T end +add_tfunc(add_ptr, 2, 2, pointerarith_tfunc, 1) +add_tfunc(sub_ptr, 2, 2, pointerarith_tfunc, 1) add_tfunc(pointerref, 3, 3, pointerref_tfunc, 4) add_tfunc(pointerset, 4, 4, pointerset_tfunc, 5) add_tfunc(atomic_fence, 1, 1, atomic_fence_tfunc, 4) diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 844a5ca8338c7..a727eee445457 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -1158,10 +1158,8 @@ JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a, jl_value_t *b, jl_value_t *c) un_iintrinsic_fast(LLVMNeg, neg, neg_int, u) #define add(a,b) a + b bi_iintrinsic_fast(LLVMAdd, add, add_int, u) -bi_iintrinsic_fast(LLVMAdd, add, add_ptr, u) #define sub(a,b) a - b bi_iintrinsic_fast(LLVMSub, sub, sub_int, u) -bi_iintrinsic_fast(LLVMSub, sub, sub_ptr, u) #define mul(a,b) a * b bi_iintrinsic_fast(LLVMMul, mul, mul_int, u) #define div(a,b) a / b @@ -1472,3 +1470,19 @@ JL_DLLEXPORT jl_value_t *jl_have_fma(jl_value_t *typ) else return jl_false; } + +JL_DLLEXPORT jl_value_t *jl_add_ptr(jl_value_t *ptr, jl_value_t *offset) +{ + JL_TYPECHK(add_ptr, pointer, ptr); + JL_TYPECHK(add_ptr, ulong, offset); + char *ptrval = (char*)jl_unbox_long(ptr) + jl_unbox_ulong(offset); + return jl_new_bits(jl_typeof(ptr), &ptrval); +} + +JL_DLLEXPORT jl_value_t *jl_sub_ptr(jl_value_t *ptr, jl_value_t *offset) +{ + JL_TYPECHK(sub_ptr, pointer, ptr); + JL_TYPECHK(sub_ptr, ulong, offset); + char *ptrval = (char*)jl_unbox_long(ptr) - jl_unbox_ulong(offset); + return jl_new_bits(jl_typeof(ptr), &ptrval); +} diff --git a/test/intrinsics.jl b/test/intrinsics.jl index 3c49afe2c4d7e..c686401989818 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -361,3 +361,11 @@ Base.show(io::IO, a::IntWrap) = print(io, "IntWrap(", a.x, ")") @test r2 isa IntWrap && r2.x === 103 === r[].x && r2 !== r[] end end)() + +@testset "Pointer Arithmatic" begin + @test_intrinsic Core.Intrinsics.add_ptr Ptr{Int}(1) UInt(1) Ptr{Int}(2) + @test_throws TypeError Core.Intrinsics.add_ptr(Ptr{Int}(1), 1) + @test_intrinsic Core.Intrinsics.sub_ptr Ptr{Int}(1) UInt(1) Ptr{Int}(0) + @test_throws TypeError Core.Intrinsics.sub_ptr(Ptr{Int}(1), 1) +end +