From d90fbe3a0ab69e9a01d68e1f93bf37dec242e72e Mon Sep 17 00:00:00 2001 From: monojenkins Date: Tue, 30 Oct 2018 11:13:29 -0400 Subject: [PATCH] [llvm] Fix passing vtypes received by value as arguments, they need to be copied. Fixes https://github.com/mono/mono/issues/11378. (#11429) --- mono/mini/mini-llvm.c | 11 +++++++++-- mono/mini/objects.cs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 9deed7a2cad2..18a9210f949e 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -5917,8 +5917,15 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) addresses [ins->sreg1] = build_alloca (ctx, t); g_assert (values [ins->sreg1]); LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]); + addresses [ins->dreg] = addresses [ins->sreg1]; + } else if (values [ins->sreg1] == addresses [ins->sreg1]) { + /* LLVMArgVtypeByRef, have to make a copy */ + addresses [ins->dreg] = build_alloca (ctx, t); + LLVMValueRef v = LLVMBuildLoad (builder, addresses [ins->sreg1], ""); + LLVMBuildStore (builder, convert (ctx, v, type_to_llvm_type (ctx, t)), addresses [ins->dreg]); + } else { + addresses [ins->dreg] = addresses [ins->sreg1]; } - addresses [ins->dreg] = addresses [ins->sreg1]; } break; } @@ -7195,7 +7202,7 @@ emit_method_inner (EmitContext *ctx) else name = g_strdup_printf ("arg_%d", i); } - LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name); + LLVMSetValueName (LLVMGetParam (method, pindex), name); g_free (name); if (ainfo->storage == LLVMArgVtypeByVal) mono_llvm_add_param_attr (LLVMGetParam (method, pindex), LLVM_ATTR_BY_VAL); diff --git a/mono/mini/objects.cs b/mono/mini/objects.cs index 33c393f33548..4ad7fb70abd1 100644 --- a/mono/mini/objects.cs +++ b/mono/mini/objects.cs @@ -1964,6 +1964,41 @@ class SimpleContainer { public static int test_0_dup_vtype () { return new SimpleContainer ().SetFields (); } + + public struct Vec3 { + public int X, Y, Z; + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public Vec3(int x, int y, int z) { + X = x; + Y = y; + Z = z; + } + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static int gh_11378_inner_1 (Vec3 p1, Vec3 p2) { + p1.X -= p2.X; + p1.Y -= p2.Y; + p1.Z -= p2.Z; + + return (int)p2.Y; + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static int gh_11378_inner_2 (Vec3 c, Vec3 pos) { + return gh_11378_inner_1 (pos, c); + } + + static int gh_11378_inner_3 (Vec3 c) { + var c2 = c; + return gh_11378_inner_2 (c, c2); + } + + public static int test_2_gh_11378 () { + return gh_11378_inner_3 (new Vec3(0, 2, -20)); + } + } #if __MOBILE__