From dd985106e802933a9898add7a12cb2c9497e56a5 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 26 Jun 2019 14:46:08 -0400 Subject: [PATCH] codegen,tbaa: fix array isassigned tbaa information (#32356) This avoids a regression (correctness and performance) caused by #21262 where we were no longer able to fold away the isnull assertion in the case where the source also contains an explicit isassigned check. Also upgrade many other CreateInBoundsGEP calls to include the element type (NFC). (cherry picked from commit a7427aac76b496f68a10cdd59d0dffe4f0d8bede) --- src/ccall.cpp | 8 ++++---- src/cgutils.cpp | 39 +++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 9cf25cf8a33ff..baded9e5b8c7e 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1669,10 +1669,10 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) } else if (!jl_has_free_typevars(ety)) { Value *idx = emit_unbox(ctx, T_size, idxv, (jl_value_t*)jl_ulong_type); - Value *arrayptr = emit_bitcast(ctx, emit_arrayptr(ctx, aryv, aryex), T_ppjlvalue); - Value *slot_addr = ctx.builder.CreateGEP(arrayptr, idx); - Value *load = tbaa_decorate(tbaa_arraybuf, ctx.builder.CreateLoad(slot_addr)); - Value *res = ctx.builder.CreateZExt(ctx.builder.CreateICmpNE(load, V_null), T_int32); + Value *arrayptr = emit_bitcast(ctx, emit_arrayptr(ctx, aryv, aryex), T_pprjlvalue); + Value *slot_addr = ctx.builder.CreateInBoundsGEP(T_prjlvalue, arrayptr, idx); + Value *load = tbaa_decorate(tbaa_ptrarraybuf, ctx.builder.CreateLoad(T_prjlvalue, slot_addr)); + Value *res = ctx.builder.CreateZExt(ctx.builder.CreateICmpNE(load, Constant::getNullValue(T_prjlvalue)), T_int32); JL_GC_POP(); return mark_or_box_ccall_result(ctx, res, retboxed, rt, unionall, static_rt); } diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 13faef984574e..db0821fd9e8ac 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -785,13 +785,18 @@ static unsigned get_box_tindex(jl_datatype_t *jt, jl_value_t *ut) static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, ssize_t n, bool gctracked = true) { - return ctx.builder.CreateInBoundsGEP(emit_bitcast(ctx, maybe_decay_tracked(v), T_pprjlvalue), - ConstantInt::get(T_size, n)); + return ctx.builder.CreateInBoundsGEP( + T_prjlvalue, + emit_bitcast(ctx, maybe_decay_tracked(v), T_pprjlvalue), + ConstantInt::get(T_size, n)); } static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, Value *idx) { - return ctx.builder.CreateInBoundsGEP(emit_bitcast(ctx, maybe_decay_tracked(v), T_pprjlvalue), idx); + return ctx.builder.CreateInBoundsGEP( + T_prjlvalue, + emit_bitcast(ctx, maybe_decay_tracked(v), T_pprjlvalue), + idx); } static Value *emit_nthptr(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa) @@ -1482,8 +1487,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx, minimum_align = std::min(minimum_align, (size_t)julia_alignment(ft)); } - Value *fldptr = ctx.builder.CreateInBoundsGEP(maybe_decay_tracked( - emit_bitcast(ctx, data_pointer(ctx, strct), T_pprjlvalue)), idx); + Value *fldptr = ctx.builder.CreateInBoundsGEP( + T_prjlvalue, + maybe_decay_tracked(emit_bitcast(ctx, data_pointer(ctx, strct), T_pprjlvalue)), + idx); Value *fld = tbaa_decorate(strct.tbaa, maybe_mark_load_dereferenceable( ctx.builder.CreateLoad(T_prjlvalue, fldptr), @@ -1565,8 +1572,9 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st // can pessimize mem2reg if (byte_offset > 0) { addr = ctx.builder.CreateInBoundsGEP( - emit_bitcast(ctx, staddr, T_pint8), - ConstantInt::get(T_size, byte_offset)); + T_int8, + emit_bitcast(ctx, staddr, T_pint8), + ConstantInt::get(T_size, byte_offset)); } else { addr = staddr; @@ -1921,8 +1929,8 @@ static Value *emit_array_nd_index( ctx.builder.SetInsertPoint(failBB); // CreateAlloca is OK here since we are on an error branch Value *tmp = ctx.builder.CreateAlloca(T_size, ConstantInt::get(T_size, nidxs)); - for(size_t k=0; k < nidxs; k++) { - ctx.builder.CreateStore(idxs[k], ctx.builder.CreateInBoundsGEP(tmp, ConstantInt::get(T_size, k))); + for (size_t k = 0; k < nidxs; k++) { + ctx.builder.CreateStore(idxs[k], ctx.builder.CreateInBoundsGEP(T_size, tmp, ConstantInt::get(T_size, k))); } ctx.builder.CreateCall(prepare_call(jlboundserrorv_func), { mark_callee_rooted(a), tmp, ConstantInt::get(T_size, nidxs) }); @@ -2435,8 +2443,9 @@ static void emit_setfield(jl_codectx_t &ctx, Value *addr = data_pointer(ctx, strct); if (byte_offset > 0) { addr = ctx.builder.CreateInBoundsGEP( - emit_bitcast(ctx, maybe_decay_tracked(addr), T_pint8), - ConstantInt::get(T_size, byte_offset)); // TODO: use emit_struct_gep + T_int8, + emit_bitcast(ctx, maybe_decay_tracked(addr), T_pint8), + ConstantInt::get(T_size, byte_offset)); // TODO: use emit_struct_gep } jl_value_t *jfty = jl_svecref(sty->types, idx0); if (jl_field_isptr(sty, idx0)) { @@ -2558,7 +2567,9 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg if (!jl_field_isptr(sty, i) && jl_is_uniontype(jl_field_type(sty, i))) { tbaa_decorate(tbaa_unionselbyte, ctx.builder.CreateStore( ConstantInt::get(T_int8, 0), - ctx.builder.CreateInBoundsGEP(emit_bitcast(ctx, strct, T_pint8), + ctx.builder.CreateInBoundsGEP( + T_int8, + emit_bitcast(ctx, strct, T_pint8), ConstantInt::get(T_size, jl_field_offset(sty, i) + jl_field_size(sty, i) - 1)))); } } @@ -2578,7 +2589,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg tbaa_decorate(strctinfo.tbaa, ctx.builder.CreateStore( ConstantPointerNull::get(cast(T_prjlvalue)), ctx.builder.CreateInBoundsGEP(T_prjlvalue, emit_bitcast(ctx, strct, T_pprjlvalue), - ConstantInt::get(T_size, jl_field_offset(sty, i) / sizeof(void*))))); + ConstantInt::get(T_size, jl_field_offset(sty, i) / sizeof(void*))))); } } for (size_t i = nargs; i < nf; i++) { @@ -2586,7 +2597,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg tbaa_decorate(tbaa_unionselbyte, ctx.builder.CreateStore( ConstantInt::get(T_int8, 0), ctx.builder.CreateInBoundsGEP(emit_bitcast(ctx, strct, T_pint8), - ConstantInt::get(T_size, jl_field_offset(sty, i) + jl_field_size(sty, i) - 1)))); + ConstantInt::get(T_size, jl_field_offset(sty, i) + jl_field_size(sty, i) - 1)))); } } bool need_wb = false;