@@ -2588,7 +2588,9 @@ static jl_cgval_t convert_julia_type_to_union(jl_codectx_t &ctx, const jl_cgval_
25882588 if (!v.isboxed && v.V && v.inline_roots .empty () && !v.ispointer ()) {
25892589 // previous value was unboxed (leaftype) and hoisted (!pointer) with statically computed union tindex
25902590 // TODO: remove this branch once all consumers of v.TIndex understand how to handle a non-ispointer value
2591- return jl_cgval_t (value_to_pointer (ctx, v), typ, new_tindex);
2591+ jl_cgval_t ret (value_to_pointer (ctx, v), typ, new_tindex);
2592+ ret.inline_roots = ExtractTrackedValues (v.V , v.V ->getType (), false , ctx.builder );
2593+ return ret;
25922594 }
25932595 }
25942596 else if (jl_subtype (v.typ , typ)) {
@@ -9501,7 +9503,7 @@ static jl_llvm_functions_t
95019503 isboxed_union = ConstantInt::get (getInt1Ty (ctx.builder .getContext ()), 1 );
95029504 }
95039505 else if (!returninfo.return_roots ) {
9504- if (retvalinfo.V == NULL ) {
9506+ if (retvalinfo.V == NULL && retvalinfo. inline_roots . empty () ) {
95059507 // treat this as a simple Ghosts
95069508 sret = NULL ;
95079509 }
@@ -9534,17 +9536,19 @@ static jl_llvm_functions_t
95349536 Value *Vnull = Constant::getNullValue (ctx.types ().T_prjlvalue );
95359537 SmallVector<Value*,0 > inline_roots (returninfo.return_roots , Vnull);
95369538 emit_unionmove (ctx, sret, jlrettype, MutableArrayRef (inline_roots), ctx.tbaa ().tbaa_stack , retvalinfo, /* skip*/ isboxed_union);
9539+ // TODO: shrink-wrap this store to drop any Vnull?
95379540 store_all_roots (ctx, inline_roots, return_roots, roots_ai, false );
95389541 }
9539- else if (retvalinfo.V == nullptr && !retvalinfo.inline_roots .empty ()) {
9540- // not returning into roots and don't have a value: might just have roots (might also be all ghost)
9542+ else if (!retvalinfo.inline_roots .empty ()) {
9543+ // not returning into roots but have roots, means all of them must be roots
9544+ // If we have `V`, should we use a memcpy instead?
95419545 store_all_roots (ctx, ArrayRef (retvalinfo.inline_roots ).slice (0 , std::min (retvalinfo.inline_roots .size (), (size_t )returninfo.union_bytes / sizeof (void *))),
95429546 sret, roots_ai, false );
95439547 }
95449548 else if (retvalinfo.ispointer ()) {
95459549 emit_unionmove (ctx, sret, jlrettype, /* inline_roots*/ MutableArrayRef<Value*>(), /* tbaa_dst*/ nullptr , retvalinfo, /* skip*/ isboxed_union);
95469550 }
9547- else {
9551+ else if (retvalinfo. V ) {
95489552 Align align (returninfo.union_align );
95499553 ctx.builder .CreateAlignedStore (retvalinfo.V , sret, align);
95509554 assert (retvalinfo.TIndex == NULL && " unreachable" ); // unimplemented representation
0 commit comments