From ca28b5f938e4a83958e1bab811c1c8d7961022e6 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 17 Sep 2017 00:37:31 -0400 Subject: [PATCH] Fix ccall return value boxing on ARM/AArch64 We previously relies on the extra allocation from the GC to keep the stores inbounds. This is broken by the allocation optimization since the stack allocation will only have the requested bytes and not more. --- src/ccall.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 350fa016fd788..9834376258e8e 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -2087,21 +2087,26 @@ jl_cgval_t function_sig_t::emit_a_ccall( size_t rtsz = jl_datatype_size(rt); assert(rtsz > 0); Value *strct = emit_allocobj(ctx, rtsz, runtime_bt); + MDNode *tbaa = jl_is_mutable(rt) ? tbaa_mutab : tbaa_immut; int boxalign = jl_datatype_align(rt); -#ifndef JL_NDEBUG + // copy the data from the return value to the new struct #if JL_LLVM_VERSION >= 40000 const DataLayout &DL = jl_data_layout; #else const DataLayout &DL = jl_ExecutionEngine->getDataLayout(); #endif - // ARM and AArch64 can use a LLVM type larger than the julia - // type. However, the LLVM type size should be no larger than - // the GC allocation size. (multiple of `sizeof(void*)`) - assert(DL.getTypeStoreSize(lrt) <= LLT_ALIGN(rtsz, boxalign)); -#endif - // copy the data from the return value to the new struct - MDNode *tbaa = jl_is_mutable(rt) ? tbaa_mutab : tbaa_immut; - init_bits_value(ctx, strct, result, tbaa, boxalign); + auto resultTy = result->getType(); + if (DL.getTypeStoreSize(resultTy) > rtsz) { + // ARM and AArch64 can use a LLVM type larger than the julia type. + // When this happens, cast through memory. + auto slot = emit_static_alloca(ctx, resultTy); + slot->setAlignment(boxalign); + ctx.builder.CreateAlignedStore(result, slot, boxalign); + emit_memcpy(ctx, strct, slot, rtsz, boxalign, tbaa); + } + else { + init_bits_value(ctx, strct, result, tbaa, boxalign); + } return mark_julia_type(ctx, strct, true, rt); } jlretboxed = false; // trigger mark_or_box_ccall_result to build the runtime box