diff --git a/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch b/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch index 53ad34cd6a410..b8753b0439ba0 100644 --- a/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch +++ b/deps/patches/llvm-D37939-Mem2Reg-Also-handle-memcpy.patch @@ -113,15 +113,18 @@ index ac28f59..b08a0a1 100644 return false; } else if (const GetElementPtrInst *GEPI = dyn_cast(U)) { if (GEPI->getType() != Type::getInt8PtrTy(U->getContext(), AS)) -@@ -181,7 +235,9 @@ public: +@@ -181,7 +235,13 @@ public: /// This code only looks at accesses to allocas. static bool isInterestingInstruction(const Instruction *I) { ++ if (isa(I)) { ++ const MemCpyInst *MCI = cast(I); ++ return isa(MCI->getSource()) || ++ isa(MCI->getDest()); ++ } else { return (isa(I) && isa(I->getOperand(0))) || -- (isa(I) && isa(I->getOperand(1))); -+ (isa(I) && isa(I->getOperand(1))) || -+ (isa(I) && (isa(I->getOperand(0)) || -+ isa(I->getOperand(1)))); + (isa(I) && isa(I->getOperand(1))); } ++ } /// Get or calculate the index of the specified instruction. @@ -208,6 +264,25 @@ public: diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 16fa6a8df5e1d..359923022766b 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -2067,13 +2067,14 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, const jl_cgval_t &src } else { Value *src_ptr = data_pointer(ctx, src); - if (skip) // copy dest -> dest to simulate an undef value / conditional copy - src_ptr = ctx.builder.CreateSelect(skip, - maybe_bitcast(ctx, dest, T_pint8), - maybe_bitcast(ctx, src_ptr, T_pint8)); unsigned nb = jl_datatype_size(typ); + Value *nbytes = ConstantInt::get(T_size, nb); + if (skip) // copy dest -> dest to simulate an undef value / conditional copy + nbytes = ctx.builder.CreateSelect(skip, + ConstantInt::get(T_size, 0), + nbytes); unsigned alignment = 0; - ctx.builder.CreateMemCpy(dest, src_ptr, nb, alignment, isVolatile, tbaa); + ctx.builder.CreateMemCpy(dest, src_ptr, nbytes, alignment, isVolatile, tbaa); } } } diff --git a/src/codegen.cpp b/src/codegen.cpp index ab3c36adfa9a2..c0552c446a73c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2134,8 +2134,8 @@ static Value *emit_bits_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1, const if (sz > 512 && !((jl_datatype_t*)arg1.typ)->layout->haspadding) { Value *answer = ctx.builder.CreateCall(prepare_call(memcmp_derived_func), { - maybe_bitcast(ctx, data_pointer(ctx, arg1), T_pint8), - maybe_bitcast(ctx, data_pointer(ctx, arg2), T_pint8), + maybe_bitcast(ctx, decay_derived(data_pointer(ctx, arg1)), T_pint8), + maybe_bitcast(ctx, decay_derived(data_pointer(ctx, arg2)), T_pint8), ConstantInt::get(T_size, sz) }); return ctx.builder.CreateICmpEQ(answer, ConstantInt::get(T_int32, 0)); @@ -3433,13 +3433,19 @@ static void emit_vi_assignment_unboxed(jl_codectx_t &ctx, jl_varinfo_t &vi, Valu tbaa = NULL; if (vi.pTIndex == NULL) { assert(jl_is_leaf_type(vi.value.typ)); - Value *copy_bytes = ConstantInt::get(T_int32, jl_datatype_size(vi.value.typ)); - ctx.builder.CreateMemCpy(vi.value.V, - data_pointer(ctx, rval_info), - copy_bytes, - jl_datatype_align(rval_info.typ), - vi.isVolatile, - tbaa); + // Sometimes we can get into situations where the LHS and RHS + // are the same slot. We're not allowed to memcpy in that case + // under penalty of undefined behavior. This check should catch + // the relevant situations. + if (vi.value.V != rval_info.V) { + Value *copy_bytes = ConstantInt::get(T_int32, jl_datatype_size(vi.value.typ)); + ctx.builder.CreateMemCpy(vi.value.V, + data_pointer(ctx, rval_info), + copy_bytes, + jl_datatype_align(rval_info.typ), + vi.isVolatile, + tbaa); + } } else { emit_unionmove(ctx, vi.value.V, rval_info, isboxed, vi.isVolatile, tbaa); @@ -4301,7 +4307,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t } else if (T->isAggregateType()) { // aggregate types are passed by pointer - arg = maybe_bitcast(ctx, data_pointer(ctx, inputarg), + arg = maybe_bitcast(ctx, decay_derived(data_pointer(ctx, inputarg)), T->getPointerTo()); } else {