@@ -386,8 +386,8 @@ static unsigned julia_alignment(jl_value_t *jt)
386
386
}
387
387
assert (jl_is_datatype (jt) && ((jl_datatype_t *)jt)->layout );
388
388
unsigned alignment = jl_datatype_align (jt);
389
- assert (alignment <= JL_HEAP_ALIGNMENT);
390
- assert (JL_HEAP_ALIGNMENT % alignment == 0 ) ;
389
+ if (alignment > JL_HEAP_ALIGNMENT)
390
+ return JL_HEAP_ALIGNMENT ;
391
391
return alignment;
392
392
}
393
393
@@ -594,7 +594,7 @@ static unsigned jl_field_align(jl_datatype_t *dt, size_t i)
594
594
unsigned al = jl_field_offset (dt, i);
595
595
al |= 16 ;
596
596
al &= -al;
597
- return std::min (al, jl_datatype_align (dt));
597
+ return std::min ({ al, ( unsigned ) jl_datatype_align (dt), ( unsigned )JL_HEAP_ALIGNMENT} );
598
598
}
599
599
600
600
static Type *julia_struct_to_llvm (jl_value_t *jt, jl_unionall_t *ua, bool *isboxed, bool llvmcall)
@@ -636,7 +636,6 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox
636
636
if (jst->layout ) {
637
637
assert (isptr == jl_field_isptr (jst, i));
638
638
assert ((isptr ? sizeof (void *) : fsz + jl_is_uniontype (ty)) == jl_field_size (jst, i));
639
- assert (al <= jl_field_align (jst, i));
640
639
}
641
640
Type *lty;
642
641
if (isptr) {
@@ -647,8 +646,15 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox
647
646
lty = T_int8;
648
647
}
649
648
else if (jl_is_uniontype (ty)) {
650
- // pick an Integer type size such that alignment will be correct
651
- // and always end with an Int8 (selector byte)
649
+ // pick an Integer type size such that alignment will generally be correct,
650
+ // and always end with an Int8 (selector byte).
651
+ // We may need to insert padding first to get to the right offset
652
+ if (al > MAX_ALIGN) {
653
+ Type *AlignmentType = ArrayType::get (VectorType::get (T_int8, al), 0 );
654
+ latypes.push_back (AlignmentType);
655
+ al = MAX_ALIGN;
656
+ }
657
+ assert (al <= jl_field_align (jst, i));
652
658
Type *AlignmentType = IntegerType::get (jl_LLVMContext, 8 * al);
653
659
unsigned NumATy = fsz / al;
654
660
unsigned remainder = fsz % al;
@@ -1212,7 +1218,7 @@ static Value *emit_isconcrete(jl_codectx_t &ctx, Value *typ)
1212
1218
{
1213
1219
Value *isconcrete;
1214
1220
isconcrete = ctx.builder .CreateConstInBoundsGEP1_32 (T_int8, emit_bitcast (ctx, decay_derived (typ), T_pint8), offsetof (jl_datatype_t , isconcretetype));
1215
- isconcrete = ctx.builder .CreateLoad (isconcrete, tbaa_const);
1221
+ isconcrete = ctx.builder .CreateLoad (T_int8, isconcrete, tbaa_const);
1216
1222
isconcrete = ctx.builder .CreateTrunc (isconcrete, T_int1);
1217
1223
return isconcrete;
1218
1224
}
@@ -1336,7 +1342,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
1336
1342
// }
1337
1343
// else {
1338
1344
load = ctx.builder .CreateAlignedLoad (data,
1339
- isboxed || alignment ? alignment : julia_alignment (jltype),
1345
+ isboxed || alignment ? alignment : julia_alignment (jltype),
1340
1346
false );
1341
1347
if (aliasscope)
1342
1348
load->setMetadata (" alias.scope" , aliasscope);
@@ -2434,7 +2440,8 @@ static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &vinfo)
2434
2440
static void emit_unionmove (jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, const jl_cgval_t &src, Value *skip, bool isVolatile=false )
2435
2441
{
2436
2442
if (AllocaInst *ai = dyn_cast<AllocaInst>(dest))
2437
- ctx.builder .CreateStore (UndefValue::get (ai->getAllocatedType ()), ai);
2443
+ // TODO: make this a lifetime_end & dereferencable annotation?
2444
+ ctx.builder .CreateAlignedStore (UndefValue::get (ai->getAllocatedType ()), ai, ai->getAlignment ());
2438
2445
if (jl_is_concrete_type (src.typ ) || src.constant ) {
2439
2446
jl_value_t *typ = src.constant ? jl_typeof (src.constant ) : src.typ ;
2440
2447
Type *store_ty = julia_type_to_llvm (typ);
@@ -2613,7 +2620,7 @@ static void emit_setfield(jl_codectx_t &ctx,
2613
2620
Value *tindex = compute_tindex_unboxed (ctx, rhs_union, jfty);
2614
2621
tindex = ctx.builder .CreateNUWSub (tindex, ConstantInt::get (T_int8, 1 ));
2615
2622
Value *ptindex = ctx.builder .CreateInBoundsGEP (T_int8, emit_bitcast (ctx, maybe_decay_tracked (addr), T_pint8), ConstantInt::get (T_size, fsz));
2616
- tbaa_decorate (tbaa_unionselbyte, ctx.builder .CreateStore (tindex, ptindex));
2623
+ tbaa_decorate (tbaa_unionselbyte, ctx.builder .CreateStore ( tindex, ptindex));
2617
2624
// copy data
2618
2625
if (!rhs.isghost ) {
2619
2626
emit_unionmove (ctx, addr, strct.tbaa , rhs, nullptr );
@@ -2694,7 +2701,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
2694
2701
if (jl_field_isptr (sty, i)) {
2695
2702
fval = boxed (ctx, fval_info);
2696
2703
if (!init_as_value)
2697
- tbaa_decorate (tbaa_stack, ctx.builder .CreateStore (fval, dest));
2704
+ tbaa_decorate (tbaa_stack, ctx.builder .CreateAlignedStore (fval, dest, jl_field_align (sty, i) ));
2698
2705
}
2699
2706
else if (jl_is_uniontype (jtype)) {
2700
2707
// compute tindex from rhs
0 commit comments