From: Zoltan Varga Date: Wed, 10 Feb 2016 05:46:57 +0000 (-0500) Subject: [llvmonly] Fix a few issues passing and returning vtypes smaller than one machine... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=8fde659b0d8ccfd7ae97ce39e71f0935d979f29d;p=mono.git [llvmonly] Fix a few issues passing and returning vtypes smaller than one machine word. --- diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 917abaa8555..3484ed3faec 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -1259,11 +1259,18 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo * case LLVMArgVtypeByVal: /* Vtype returned normally by val */ break; - case LLVMArgVtypeAsScalar: + case LLVMArgVtypeAsScalar: { + int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL); /* LLVM models this by returning an int */ - g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2); - ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8); + if (size < SIZEOF_VOID_P) { + g_assert (cinfo->ret.nslots == 1); + ret_type = LLVMIntType (size * 8); + } else { + g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2); + ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8); + } break; + } case LLVMArgFpStruct: { /* Vtype returned as a fp struct */ LLVMTypeRef members [16]; @@ -2906,11 +2913,20 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder) } case LLVMArgAsIArgs: { LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex); + int size; + /* The argument is received as an array of ints, store it into the real argument */ ctx->addresses [reg] = build_alloca (ctx, ainfo->type); - /* The argument is received as an array of ints, store it into the real argument */ - LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0))); + size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL); + if (size < SIZEOF_VOID_P) { + /* The upper bits of the registers might not be valid */ + LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, ""); + LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0)); + LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest); + } else { + LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0))); + } break; } case LLVMArgVtypeAsScalar: