@@ -17,8 +17,7 @@ STATISTIC(EmittedRuntimeCalls, "Number of runtime intrinsic calls emitted");
1717STATISTIC (EmittedIntrinsics, " Number of intrinsic calls emitted" 
1818STATISTIC (Emitted_pointerref, " Number of pointerref calls emitted" 
1919STATISTIC (Emitted_pointerset, " Number of pointerset calls emitted" 
20- STATISTIC (Emitted_add_ptr, " Number of add_ptr calls emitted" 
21- STATISTIC (Emitted_sub_ptr, " Number of sub_ptr calls emitted" 
20+ STATISTIC (Emitted_pointerarith, " Number of pointer arithmetic calls emitted" 
2221STATISTIC (Emitted_atomic_fence, " Number of atomic_fence calls emitted" 
2322STATISTIC (Emitted_atomic_pointerref, " Number of atomic_pointerref calls emitted" 
2423STATISTIC (Emitted_atomic_pointerop, " Number of atomic_pointerop calls emitted" 
@@ -860,6 +859,34 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, ArrayRef<jl_cgval_t> argv)
860859    return  e;
861860}
862861
862+ //  ptr + offset
863+ //  ptr - offset
864+ static  jl_cgval_t  emit_pointerarith (jl_codectx_t  &ctx, intrinsic f,
865+                                     ArrayRef<jl_cgval_t > argv)
866+ {
867+     jl_value_t  *ptrtyp = argv[0 ].typ ;
868+     jl_value_t  *offtyp = argv[1 ].typ ;
869+     if  (!jl_is_cpointer_type (ptrtyp) || offtyp != (jl_value_t  *)jl_ulong_type)
870+         return  emit_runtime_call (ctx, f, argv, argv.size ());
871+     assert (f == add_ptr || f == sub_ptr);
872+ 
873+     Value *ptr = emit_unbox (ctx, ctx.types ().T_ptr , argv[0 ], ptrtyp);
874+     Value *off = emit_unbox (ctx, ctx.types ().T_size , argv[1 ], offtyp);
875+     if  (f == sub_ptr)
876+         off = ctx.builder .CreateNeg (off);
877+     Value *ans = ctx.builder .CreateGEP (getInt8Ty (ctx.builder .getContext ()), ptr, off);
878+ 
879+     if  (jl_is_concrete_type (ptrtyp)) {
880+         return  mark_julia_type (ctx, ans, false , ptrtyp);
881+     }
882+     else  {
883+         Value *box = emit_allocobj (ctx, (jl_datatype_t  *)ptrtyp, true );
884+         setName (ctx.emission_context , box, " ptr_box" 
885+         init_bits_value (ctx, box, ans, ctx.tbaa ().tbaa_immut );
886+         return  mark_julia_type (ctx, box, true , (jl_datatype_t  *)ptrtyp);
887+     }
888+ }
889+ 
863890static  jl_cgval_t  emit_atomicfence (jl_codectx_t  &ctx, ArrayRef<jl_cgval_t > argv)
864891{
865892    const  jl_cgval_t  &ord = argv[0 ];
@@ -1278,29 +1305,11 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar
12781305        assert (nargs == 4 );
12791306        return  emit_pointerset (ctx, argv);
12801307
1281-     case  add_ptr: {
1282-         ++Emitted_add_ptr;
1308+     case  add_ptr:
1309+     case  sub_ptr:
1310+         ++Emitted_pointerarith;
12831311        assert (nargs == 2 );
1284-         if  (!jl_is_cpointer_type (argv[0 ].typ ) || jl_has_free_typevars (argv[0 ].typ ) ||
1285-             argv[1 ].typ  != (jl_value_t *)jl_ulong_type)
1286-             return  emit_runtime_call (ctx, f, argv, nargs);
1287-         Value *ptr = emit_unbox (ctx, ctx.types ().T_ptr , argv[0 ], argv[0 ].typ );
1288-         Value *off = emit_unbox (ctx, ctx.types ().T_size , argv[1 ], argv[1 ].typ );
1289-         Value *ans = ctx.builder .CreateGEP (getInt8Ty (ctx.builder .getContext ()), ptr, off);
1290-         return  mark_julia_type (ctx, ans, false , argv[0 ].typ );
1291-     }
1292-     case  sub_ptr: {
1293-         ++Emitted_sub_ptr;
1294-         assert (nargs == 2 );
1295-         if  (!jl_is_cpointer_type (argv[0 ].typ ) || jl_has_free_typevars (argv[0 ].typ ) ||
1296-             argv[1 ].typ  != (jl_value_t *)jl_ulong_type)
1297-             return  emit_runtime_call (ctx, f, argv, nargs);
1298-         Value *ptr = emit_unbox (ctx, ctx.types ().T_ptr , argv[0 ], argv[0 ].typ );
1299-         Value *off = emit_unbox (ctx, ctx.types ().T_size , argv[1 ], argv[1 ].typ );
1300-         Value *ans = ctx.builder .CreateGEP (getInt8Ty (ctx.builder .getContext ()), ptr,
1301-                                            ctx.builder .CreateNeg (off));
1302-         return  mark_julia_type (ctx, ans, false , argv[0 ].typ );
1303-     }
1312+         return  emit_pointerarith (ctx, f, argv);
13041313
13051314    case  atomic_fence:
13061315        ++Emitted_atomic_fence;
0 commit comments