@@ -409,10 +409,25 @@ Value *llvm_type_rewrite(Value *v, Type *from_type, Type *target_type,
409
409
// one or both of from_type and target_type is a VectorType or AggregateType
410
410
// LLVM doesn't allow us to cast these values directly, so
411
411
// we need to use this alloca copy trick instead
412
- // NOTE: it is assumed that the ABI has ensured that sizeof(from_type) == sizeof(target_type)
413
- Value *mem = emit_static_alloca (target_type, ctx);
414
- builder.CreateStore (v, builder.CreatePointerCast (mem, from_type->getPointerTo ()));
415
- return builder.CreateLoad (mem);
412
+ // On ARM and AArch64, the ABI requires casting through memory to different
413
+ // sizes.
414
+ Value *from;
415
+ Value *to;
416
+ #if JL_LLVM_VERSION >= 30600
417
+ const DataLayout &DL = jl_ExecutionEngine->getDataLayout ();
418
+ #else
419
+ const DataLayout &DL = *jl_ExecutionEngine->getDataLayout ();
420
+ #endif
421
+ if (DL.getTypeAllocSize (target_type) >= DL.getTypeAllocSize (from_type)) {
422
+ to = emit_static_alloca (target_type, ctx);
423
+ from = builder.CreatePointerCast (to, from_type->getPointerTo ());
424
+ }
425
+ else {
426
+ from = emit_static_alloca (from_type, ctx);
427
+ to = builder.CreatePointerCast (from, target_type->getPointerTo ());
428
+ }
429
+ builder.CreateStore (v, from);
430
+ return builder.CreateLoad (to);
416
431
}
417
432
418
433
// --- argument passing and scratch space utilities ---
@@ -1839,8 +1854,23 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
1839
1854
jl_cgval_t newst = emit_new_struct (rt, 1 , NULL , ctx); // emit a new, empty struct
1840
1855
assert (newst.typ != NULL && " Type was not concrete" );
1841
1856
assert (newst.isboxed );
1857
+ size_t rtsz = jl_datatype_size (rt);
1858
+ assert (rtsz > 0 );
1859
+ int boxalign = jl_gc_alignment (rtsz);
1860
+ #ifndef NDEBUG
1861
+ #if JL_LLVM_VERSION >= 30600
1862
+ const DataLayout &DL = jl_ExecutionEngine->getDataLayout ();
1863
+ #else
1864
+ const DataLayout &DL = *jl_ExecutionEngine->getDataLayout ();
1865
+ #endif
1866
+ // ARM and AArch64 can use a LLVM type larger than the julia
1867
+ // type. However, the LLVM type size should be no larger than
1868
+ // the GC allocation size. (multiple of `sizeof(void*)`)
1869
+ assert (DL.getTypeStoreSize (lrt) <= LLT_ALIGN (jl_datatype_size (rt),
1870
+ boxalign));
1871
+ #endif
1842
1872
// copy the data from the return value to the new struct
1843
- tbaa_decorate (newst.tbaa , builder.CreateAlignedStore (result, emit_bitcast (newst.V , prt->getPointerTo ()), 16 )); // julia gc is aligned 16
1873
+ tbaa_decorate (newst.tbaa , builder.CreateAlignedStore (result, emit_bitcast (newst.V , prt->getPointerTo ()), boxalign ));
1844
1874
return newst;
1845
1875
}
1846
1876
else if (jlrt != prt) {
0 commit comments