@@ -1376,7 +1376,7 @@ static inline jl_cgval_t update_julia_type(jl_codectx_t &ctx, const jl_cgval_t &
1376
1376
return jl_cgval_t (v, typ, NULL );
1377
1377
}
1378
1378
1379
- static jl_cgval_t convert_julia_type (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ);
1379
+ static jl_cgval_t convert_julia_type (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip= nullptr );
1380
1380
1381
1381
// --- allocating local variables ---
1382
1382
@@ -1437,7 +1437,7 @@ static void CreateConditionalAbort(IRBuilder<> &irbuilder, Value *test)
1437
1437
1438
1438
#include " cgutils.cpp"
1439
1439
1440
- static jl_cgval_t convert_julia_type_union (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ)
1440
+ static jl_cgval_t convert_julia_type_union (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip )
1441
1441
{
1442
1442
// previous value was a split union, compute new index, or box
1443
1443
Value *new_tindex = ConstantInt::get (T_int8, 0x80 );
@@ -1462,6 +1462,10 @@ static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &
1462
1462
// new value doesn't need to be boxed
1463
1463
// since it isn't part of the new union
1464
1464
t = true ;
1465
+ if (skip) {
1466
+ Value *skip1 = ctx.builder .CreateICmpEQ (tindex, ConstantInt::get (T_int8, idx));
1467
+ *skip = *skip ? ctx.builder .CreateOr (*skip, skip1) : skip1;
1468
+ }
1465
1469
}
1466
1470
else {
1467
1471
// will actually need to box this element
@@ -1552,7 +1556,8 @@ static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &
1552
1556
if (v.V == NULL ) {
1553
1557
// v.V might be NULL if it was all ghost objects before
1554
1558
return jl_cgval_t (boxv, NULL , false , typ, new_tindex);
1555
- } else {
1559
+ }
1560
+ else {
1556
1561
Value *isboxv = ctx.builder .CreateIsNotNull (boxv);
1557
1562
Value *slotv;
1558
1563
MDNode *tbaa;
@@ -1584,7 +1589,7 @@ static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &
1584
1589
1585
1590
// given a value marked with type `v.typ`, compute the mapping and/or boxing to return a value of type `typ`
1586
1591
// TODO: should this set TIndex when trivial (such as 0x80 or concrete types) ?
1587
- static jl_cgval_t convert_julia_type (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ)
1592
+ static jl_cgval_t convert_julia_type (jl_codectx_t &ctx, const jl_cgval_t &v, jl_value_t *typ, Value **skip )
1588
1593
{
1589
1594
if (typ == (jl_value_t *)jl_typeofbottom_type)
1590
1595
return ghostValue (typ); // normalize TypeofBottom to Type{Union{}}
@@ -1595,6 +1600,7 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_
1595
1600
return ghostValue (typ);
1596
1601
Value *new_tindex = NULL ;
1597
1602
if (jl_is_concrete_type (typ)) {
1603
+ assert (skip == nullptr && " skip only valid for union type return" );
1598
1604
if (v.TIndex && !jl_is_pointerfree (typ)) {
1599
1605
// discovered that this union-split type must actually be isboxed
1600
1606
if (v.Vboxed ) {
@@ -1617,7 +1623,7 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_
1617
1623
else {
1618
1624
bool makeboxed = false ;
1619
1625
if (v.TIndex ) {
1620
- return convert_julia_type_union (ctx, v, typ);
1626
+ return convert_julia_type_union (ctx, v, typ, skip );
1621
1627
}
1622
1628
else if (!v.isboxed && jl_is_uniontype (typ)) {
1623
1629
// previous value was unboxed (leaftype), statically compute union tindex
@@ -1637,6 +1643,11 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_
1637
1643
else if (jl_subtype (v.typ , typ)) {
1638
1644
makeboxed = true ;
1639
1645
}
1646
+ else if (skip) {
1647
+ // undef
1648
+ *skip = ConstantInt::get (T_int1, 1 );
1649
+ return jl_cgval_t ();
1650
+ }
1640
1651
else {
1641
1652
// unreachable
1642
1653
CreateTrap (ctx.builder );
@@ -6919,12 +6930,16 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
6919
6930
V = boxed (ctx, val);
6920
6931
}
6921
6932
else {
6933
+ // XXX: must emit undef here (rather than a bitcast or
6934
+ // load of val) if the runtime type of val isn't phiType
6922
6935
V = emit_unbox (ctx, VN->getType (), val, phiType);
6923
6936
}
6924
6937
VN->addIncoming (V, ctx.builder .GetInsertBlock ());
6925
6938
assert (!TindexN);
6926
6939
}
6927
6940
else if (dest && val.typ != (jl_value_t *)jl_bottom_type) {
6941
+ // XXX: must emit undef here (rather than a bitcast or
6942
+ // load of val) if the runtime type of val isn't phiType
6928
6943
assert (lty != T_prjlvalue);
6929
6944
(void )emit_unbox (ctx, lty, val, phiType, maybe_decay_tracked (ctx, dest));
6930
6945
}
@@ -6957,7 +6972,10 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
6957
6972
}
6958
6973
}
6959
6974
else {
6960
- jl_cgval_t new_union = convert_julia_type (ctx, val, phiType);
6975
+ Value *skip = NULL ;
6976
+ // must compute skip here, since the runtime type of val might not be in phiType
6977
+ // caution: only Phi and PhiC are allowed to do this (and maybe sometimes Pi)
6978
+ jl_cgval_t new_union = convert_julia_type (ctx, val, phiType, &skip);
6961
6979
RTindex = new_union.TIndex ;
6962
6980
if (!RTindex) {
6963
6981
assert (new_union.isboxed && new_union.Vboxed && " convert_julia_type failed" );
@@ -6972,11 +6990,12 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
6972
6990
if (VN)
6973
6991
V = new_union.Vboxed ? new_union.Vboxed : V_rnull;
6974
6992
if (dest) { // basically, if !ghost union
6975
- Value *skip = NULL ;
6976
- if (new_union.Vboxed != nullptr )
6977
- skip = ctx.builder .CreateICmpNE ( // if 0x80 is set, we won't select this slot anyways
6993
+ if (new_union.Vboxed != nullptr ) {
6994
+ Value *isboxed = ctx.builder .CreateICmpNE ( // if 0x80 is set, we won't select this slot anyways
6978
6995
ctx.builder .CreateAnd (RTindex, ConstantInt::get (T_int8, 0x80 )),
6979
6996
ConstantInt::get (T_int8, 0 ));
6997
+ skip = skip ? ctx.builder .CreateOr (isboxed, skip) : isboxed;
6998
+ }
6980
6999
emit_unionmove (ctx, dest, tbaa_arraybuf, new_union, skip);
6981
7000
}
6982
7001
}
0 commit comments