Skip to content

Commit 897df72

Browse files
vtjnashJeffBezanson
authored andcommitted
codegen: disable Bool optimization for maybe-undef fields (#30350)
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
1 parent d767fcf commit 897df72

File tree

3 files changed

+6
-8
lines changed

3 files changed

+6
-8
lines changed

base/boot.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ toInt8(x::UInt16) = checked_trunc_sint(Int8, check_top_bit(x))
624624
toInt8(x::UInt32) = checked_trunc_sint(Int8, check_top_bit(x))
625625
toInt8(x::UInt64) = checked_trunc_sint(Int8, check_top_bit(x))
626626
toInt8(x::UInt128) = checked_trunc_sint(Int8, check_top_bit(x))
627-
toInt8(x::Bool) = and_int(zext_int(Int8, x), Int8(1))
627+
toInt8(x::Bool) = and_int(bitcast(Int8, x), Int8(1))
628628
toInt16(x::Int8) = sext_int(Int16, x)
629629
toInt16(x::Int16) = x
630630
toInt16(x::Int32) = checked_trunc_sint(Int16, x)
@@ -679,7 +679,7 @@ toUInt8(x::UInt16) = checked_trunc_uint(UInt8, x)
679679
toUInt8(x::UInt32) = checked_trunc_uint(UInt8, x)
680680
toUInt8(x::UInt64) = checked_trunc_uint(UInt8, x)
681681
toUInt8(x::UInt128) = checked_trunc_uint(UInt8, x)
682-
toUInt8(x::Bool) = and_int(zext_int(UInt8, x), UInt8(1))
682+
toUInt8(x::Bool) = and_int(bitcast(UInt8, x), UInt8(1))
683683
toUInt16(x::Int8) = sext_int(UInt16, check_top_bit(x))
684684
toUInt16(x::Int16) = bitcast(UInt16, check_top_bit(x))
685685
toUInt16(x::Int32) = checked_trunc_uint(UInt16, x)

src/cgutils.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,10 +1425,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
14251425
Value *idx, jl_datatype_t *stt, jl_value_t *inbounds)
14261426
{
14271427
size_t nfields = jl_datatype_nfields(stt);
1428+
bool maybe_null = (unsigned)stt->ninitialized != nfields;
14281429
if (strct.ispointer()) { // boxed or stack
14291430
if (is_datatype_all_pointers(stt)) {
14301431
idx = emit_bounds_check(ctx, strct, (jl_value_t*)stt, idx, ConstantInt::get(T_size, nfields), inbounds);
1431-
bool maybe_null = (unsigned)stt->ninitialized != nfields;
14321432
size_t minimum_field_size = std::numeric_limits<size_t>::max();
14331433
size_t minimum_align = JL_HEAP_ALIGNMENT;
14341434
for (size_t i = 0; i < nfields; ++i) {
@@ -1458,7 +1458,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
14581458
jl_value_t *jt = jl_field_type(stt, 0);
14591459
idx = emit_bounds_check(ctx, strct, (jl_value_t*)stt, idx, ConstantInt::get(T_size, nfields), inbounds);
14601460
Value *ptr = maybe_decay_tracked(data_pointer(ctx, strct));
1461-
if (!stt->mutabl) {
1461+
if (!stt->mutabl && !(maybe_null && jt == (jl_value_t*)jl_bool_type)) {
14621462
// just compute the pointer and let user load it when necessary
14631463
Type *fty = julia_type_to_llvm(jt);
14641464
Value *addr = ctx.builder.CreateInBoundsGEP(fty, emit_bitcast(ctx, ptr, PointerType::get(fty, 0)), idx);
@@ -1512,6 +1512,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
15121512
if (type_is_ghost(elty))
15131513
return ghostValue(jfty);
15141514
Value *fldv = NULL;
1515+
bool maybe_null = idx >= (unsigned)jt->ninitialized;
15151516
if (strct.ispointer()) {
15161517
Value *staddr = maybe_decay_tracked(data_pointer(ctx, strct));
15171518
bool isboxed;
@@ -1553,7 +1554,6 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
15531554
}
15541555
unsigned align = jl_field_align(jt, idx);
15551556
if (jl_field_isptr(jt, idx)) {
1556-
bool maybe_null = idx >= (unsigned)jt->ninitialized;
15571557
Instruction *Load = maybe_mark_load_dereferenceable(
15581558
ctx.builder.CreateLoad(T_prjlvalue, emit_bitcast(ctx, addr, T_pprjlvalue)),
15591559
maybe_null, jl_field_type(jt, idx));
@@ -1586,7 +1586,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
15861586
}
15871587
return mark_julia_slot(addr, jfty, tindex, strct.tbaa);
15881588
}
1589-
else if (!jt->mutabl) {
1589+
else if (!jt->mutabl && !(maybe_null && jfty == (jl_value_t*)jl_bool_type)) {
15901590
// just compute the pointer and let user load it when necessary
15911591
return mark_julia_slot(addr, jfty, NULL, strct.tbaa);
15921592
}

src/runtime_intrinsics.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,6 @@ static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const
400400
void *pr = alloca(osize);
401401
unsigned isize_bits = isize * host_char_bit;
402402
unsigned osize_bits = osize * host_char_bit;
403-
if (aty == (jl_value_t*)jl_bool_type)
404-
isize_bits = 1;
405403
op(isize_bits, pa, osize_bits, pr);
406404
return jl_new_bits(ty, pr);
407405
}

0 commit comments

Comments
 (0)