Skip to content

Commit

Permalink
codegen: disable Bool optimization for maybe-undef fields (#30350)
Browse files Browse the repository at this point in the history
We don't have a way to mark that the slot may contain invalid data,
so just eagerly load it so we can sanitize the value immediately
in case it is garbage.

fix #30344

(cherry picked from commit 897df72)
  • Loading branch information
vtjnash authored and KristofferC committed Dec 12, 2018
1 parent a9c886a commit 28d9ec2
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 8 deletions.
4 changes: 2 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ toInt8(x::UInt16) = checked_trunc_sint(Int8, check_top_bit(x))
toInt8(x::UInt32) = checked_trunc_sint(Int8, check_top_bit(x))
toInt8(x::UInt64) = checked_trunc_sint(Int8, check_top_bit(x))
toInt8(x::UInt128) = checked_trunc_sint(Int8, check_top_bit(x))
toInt8(x::Bool) = and_int(zext_int(Int8, x), Int8(1))
toInt8(x::Bool) = and_int(bitcast(Int8, x), Int8(1))
toInt16(x::Int8) = sext_int(Int16, x)
toInt16(x::Int16) = x
toInt16(x::Int32) = checked_trunc_sint(Int16, x)
Expand Down Expand Up @@ -679,7 +679,7 @@ toUInt8(x::UInt16) = checked_trunc_uint(UInt8, x)
toUInt8(x::UInt32) = checked_trunc_uint(UInt8, x)
toUInt8(x::UInt64) = checked_trunc_uint(UInt8, x)
toUInt8(x::UInt128) = checked_trunc_uint(UInt8, x)
toUInt8(x::Bool) = and_int(zext_int(UInt8, x), UInt8(1))
toUInt8(x::Bool) = and_int(bitcast(UInt8, x), UInt8(1))
toUInt16(x::Int8) = sext_int(UInt16, check_top_bit(x))
toUInt16(x::Int16) = bitcast(UInt16, check_top_bit(x))
toUInt16(x::Int32) = checked_trunc_uint(UInt16, x)
Expand Down
8 changes: 4 additions & 4 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,10 +1425,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
Value *idx, jl_datatype_t *stt, jl_value_t *inbounds)
{
size_t nfields = jl_datatype_nfields(stt);
bool maybe_null = (unsigned)stt->ninitialized != nfields;
if (strct.ispointer()) { // boxed or stack
if (is_datatype_all_pointers(stt)) {
idx = emit_bounds_check(ctx, strct, (jl_value_t*)stt, idx, ConstantInt::get(T_size, nfields), inbounds);
bool maybe_null = (unsigned)stt->ninitialized != nfields;
size_t minimum_field_size = std::numeric_limits<size_t>::max();
size_t minimum_align = JL_HEAP_ALIGNMENT;
for (size_t i = 0; i < nfields; ++i) {
Expand Down Expand Up @@ -1458,7 +1458,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
jl_value_t *jt = jl_field_type(stt, 0);
idx = emit_bounds_check(ctx, strct, (jl_value_t*)stt, idx, ConstantInt::get(T_size, nfields), inbounds);
Value *ptr = maybe_decay_tracked(data_pointer(ctx, strct));
if (!stt->mutabl) {
if (!stt->mutabl && !(maybe_null && jt == (jl_value_t*)jl_bool_type)) {
// just compute the pointer and let user load it when necessary
Type *fty = julia_type_to_llvm(jt);
Value *addr = ctx.builder.CreateInBoundsGEP(fty, emit_bitcast(ctx, ptr, PointerType::get(fty, 0)), idx);
Expand Down Expand Up @@ -1512,6 +1512,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
if (type_is_ghost(elty))
return ghostValue(jfty);
Value *fldv = NULL;
bool maybe_null = idx >= (unsigned)jt->ninitialized;
if (strct.ispointer()) {
Value *staddr = maybe_decay_tracked(data_pointer(ctx, strct));
bool isboxed;
Expand Down Expand Up @@ -1553,7 +1554,6 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
}
unsigned align = jl_field_align(jt, idx);
if (jl_field_isptr(jt, idx)) {
bool maybe_null = idx >= (unsigned)jt->ninitialized;
Instruction *Load = maybe_mark_load_dereferenceable(
ctx.builder.CreateLoad(T_prjlvalue, emit_bitcast(ctx, addr, T_pprjlvalue)),
maybe_null, jl_field_type(jt, idx));
Expand Down Expand Up @@ -1586,7 +1586,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
}
return mark_julia_slot(addr, jfty, tindex, strct.tbaa);
}
else if (!jt->mutabl) {
else if (!jt->mutabl && !(maybe_null && jfty == (jl_value_t*)jl_bool_type)) {
// just compute the pointer and let user load it when necessary
return mark_julia_slot(addr, jfty, NULL, strct.tbaa);
}
Expand Down
2 changes: 0 additions & 2 deletions src/runtime_intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,6 @@ static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const
void *pr = alloca(osize);
unsigned isize_bits = isize * host_char_bit;
unsigned osize_bits = osize * host_char_bit;
if (aty == (jl_value_t*)jl_bool_type)
isize_bits = 1;
op(isize_bits, pa, osize_bits, pr);
return jl_new_bits(ty, pr);
}
Expand Down

0 comments on commit 28d9ec2

Please sign in to comment.