From 9d652a972a015187b870c35057e7be1fa9c6852f Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 26 Mar 2019 11:28:59 -0400 Subject: [PATCH] [llvm] Fix the computation of size of gshared instances in emit_args_to_vtype (). (#13659) Fixes https://github.com/mono/mono/issues/13610. --- mono/mini/generics.cs | 14 ++++++++++++++ mono/mini/mini-llvm.c | 10 ++++++---- mono/mini/mini.h | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/mono/mini/generics.cs b/mono/mini/generics.cs index 6cb61e16e1a..857ad44f3e0 100644 --- a/mono/mini/generics.cs +++ b/mono/mini/generics.cs @@ -1448,6 +1448,20 @@ class Tests var res = builder.Caller (ref awaiter); return res == typeof (bool) ? 0 : 1; } + + struct OneThing { + public T1 Item1; + } + + [MethodImpl (MethodImplOptions.NoInlining)] + static T FromResult (T result) { + return result; + } + + public static int test_42_llvm_gsharedvt_small_vtype_in_regs () { + var t = FromResult>(new OneThing {Item1 = 42}); + return t.Item1; + } } #if !__MOBILE__ diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 0373f143663..f21b7da44ca 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -2360,12 +2360,14 @@ static void emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args) { int j, size, nslots; + MonoClass *klass; - size = mono_class_value_size (mono_class_from_mono_type_internal (t), NULL); + t = mini_get_underlying_type (t); + klass = mono_class_from_mono_type_internal (t); + size = mono_class_value_size (klass, NULL); - if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (t))) { + if (MONO_CLASS_IS_SIMD (ctx->cfg, klass)) address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), ""); - } if (ainfo->storage == LLVMArgAsFpArgs) nslots = ainfo->nslots; @@ -2386,7 +2388,7 @@ emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMV switch (ainfo->pair_storage [j]) { case LLVMArgInIReg: { part_type = LLVMIntType (part_size * 8); - if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (t))) { + if (MONO_CLASS_IS_SIMD (ctx->cfg, klass)) { index [0] = LLVMConstInt (LLVMInt32Type (), j * TARGET_SIZEOF_VOID_P, FALSE); addr = LLVMBuildGEP (builder, address, index, 1, ""); } else { diff --git a/mono/mini/mini.h b/mono/mini/mini.h index d7e182e2bdc..9358871dc93 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -623,7 +623,7 @@ typedef struct { LLVMArgStorage storage; /* - * Only if storage == ArgValuetypeInReg/LLVMArgAsFpArgs. + * Only if storage == ArgVtypeInReg/LLVMArgAsFpArgs. * This contains how the parts of the vtype are passed. */ LLVMArgStorage pair_storage [8]; -- 2.11.4.GIT