From a8d641827aed0f6aa99af32e116e3b06a6b55312 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 16 Feb 2022 20:10:46 -0800 Subject: [PATCH 01/10] Enable SIMD intrinsics for System.Numerics.Vector on Arm64 --- src/mono/mono/mini/simd-intrinsics.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 39342e8a969ca3..3d5e440a341a8e 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -3299,6 +3299,9 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign if (!strcmp (class_ns, "System.Runtime.Intrinsics")) { if (!strcmp (class_name, "Vector128") || !strcmp (class_name, "Vector64")) return emit_sri_vector (cfg, cmethod, fsig, args); + } else if (!strcmp (class_ns, "System.Numerics")){ + if (!strcmp (class_name, "Vector")) + return emit_sri_vector (cfg, cmethod, fsig, args); } if (!strcmp (class_ns, "System.Runtime.Intrinsics")) { From f9cfc680cbc8f91b21e1d5eed9c3fe75ee2dc16c Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 16 Feb 2022 20:23:53 -0800 Subject: [PATCH 02/10] Minor adjustment --- src/mono/mono/mini/simd-intrinsics.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 3d5e440a341a8e..26ea4e162ca190 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -600,13 +600,13 @@ static guint16 sri_vector_methods [] = { SN_AsUInt16, SN_AsUInt32, SN_AsUInt64, - SN_BitwiseAnd, - SN_BitwiseOr, SN_AsVector128, SN_AsVector2, SN_AsVector256, SN_AsVector3, SN_AsVector4, + SN_BitwiseAnd, + SN_BitwiseOr, SN_Ceiling, SN_ConditionalSelect, SN_Create, @@ -3299,9 +3299,6 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign if (!strcmp (class_ns, "System.Runtime.Intrinsics")) { if (!strcmp (class_name, "Vector128") || !strcmp (class_name, "Vector64")) return emit_sri_vector (cfg, cmethod, fsig, args); - } else if (!strcmp (class_ns, "System.Numerics")){ - if (!strcmp (class_name, "Vector")) - return emit_sri_vector (cfg, cmethod, fsig, args); } if (!strcmp (class_ns, "System.Runtime.Intrinsics")) { @@ -3310,6 +3307,12 @@ mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign } #endif // defined(TARGET_ARM64) || defined(TARGET_AMD64) +#if defined(TARGET_ARM64) + if (!strcmp (class_ns, "System.Numerics") && !strcmp (class_name, "Vector")){ + return emit_sri_vector (cfg, cmethod, fsig, args); + } +#endif // defined(TARGET_ARM64) + return emit_simd_intrinsics (class_ns, class_name, cfg, cmethod, fsig, args); } From 5c0e392d392daf6947b26c10d5176d0433de7a42 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Fri, 18 Feb 2022 06:52:10 -0800 Subject: [PATCH 03/10] Use the correct op code for BitwiseAnd, BitwiseOr and Xor --- src/mono/mono/mini/simd-intrinsics.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 26ea4e162ca190..f0208b26191284 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -761,13 +761,25 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; #endif case SN_BitwiseAnd: - return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, OP_IAND, arg0_type, fsig, args); case SN_BitwiseOr: - return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, OP_IOR, arg0_type, fsig, args); case SN_Xor: { - if ((arg0_type == MONO_TYPE_R4) || (arg0_type == MONO_TYPE_R8)) - return NULL; - return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, OP_IXOR, arg0_type, fsig, args); + // if ((arg0_type == MONO_TYPE_R4) || (arg0_type == MONO_TYPE_R8)) + // return NULL; + int instc0 = -1; + switch (id) { + case SN_BitwiseAnd: + instc0 = XBINOP_FORCEINT_and; + break; + case SN_BitwiseOr: + instc0 = XBINOP_FORCEINT_or; + break; + case SN_Xor: + instc0 = XBINOP_FORCEINT_xor; + break; + default: + g_assert_not_reached (); + } + return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP_FORCEINT, instc0, arg0_type, fsig, args); } case SN_As: case SN_AsByte: From 169a97c5b7604c168b541dd4a7afe532ab0e508d Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Tue, 22 Feb 2022 09:55:54 -0800 Subject: [PATCH 04/10] Check if vector element type is a primitive type or not --- src/mono/mono/mini/simd-intrinsics.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index f0208b26191284..6e550b71100435 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -684,6 +684,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi switch (id) { case SN_Abs: { + MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); + if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + return NULL; #ifdef TARGET_ARM64 switch (arg0_type) { case MONO_TYPE_U1: From dae3efd326a12ca51defc03bded6533e46759fdf Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Tue, 22 Feb 2022 10:42:05 -0800 Subject: [PATCH 05/10] Remove dead code and fix constant formet --- src/mono/mono/mini/llvm-intrinsics-types.h | 8 ++++---- src/mono/mono/mini/mini-llvm.c | 8 ++++---- src/mono/mono/mini/simd-intrinsics.c | 16 +++++++--------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/mono/mono/mini/llvm-intrinsics-types.h b/src/mono/mono/mini/llvm-intrinsics-types.h index 401daabed241b7..9801d161ed8c6d 100644 --- a/src/mono/mono/mini/llvm-intrinsics-types.h +++ b/src/mono/mono/mini/llvm-intrinsics-types.h @@ -18,10 +18,10 @@ typedef enum { } IntrinsicId; enum { - XBINOP_FORCEINT_and, - XBINOP_FORCEINT_or, - XBINOP_FORCEINT_ornot, - XBINOP_FORCEINT_xor, + XBINOP_FORCEINT_AND, + XBINOP_FORCEINT_OR, + XBINOP_FORCEINT_ORNOT, + XBINOP_FORCEINT_XOR, }; #endif /* __MONO_MINI_LLVM_INTRINSICS_TYPES_H__ */ diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 0a85c0c7a68c5d..e8ee9a5ecc18c3 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -7799,17 +7799,17 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) LLVMValueRef rhs_int = convert (ctx, rhs, intermediate_t); LLVMValueRef result = NULL; switch (ins->inst_c0) { - case XBINOP_FORCEINT_and: + case XBINOP_FORCEINT_AND: result = LLVMBuildAnd (builder, lhs_int, rhs_int, ""); break; - case XBINOP_FORCEINT_or: + case XBINOP_FORCEINT_OR: result = LLVMBuildOr (builder, lhs_int, rhs_int, ""); break; - case XBINOP_FORCEINT_ornot: + case XBINOP_FORCEINT_ORNOT: result = LLVMBuildNot (builder, rhs_int, ""); result = LLVMBuildOr (builder, result, lhs_int, ""); break; - case XBINOP_FORCEINT_xor: + case XBINOP_FORCEINT_XOR: result = LLVMBuildXor (builder, lhs_int, rhs_int, ""); break; } diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 6e550b71100435..a6b38d2ebbc70b 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -766,18 +766,16 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_BitwiseAnd: case SN_BitwiseOr: case SN_Xor: { - // if ((arg0_type == MONO_TYPE_R4) || (arg0_type == MONO_TYPE_R8)) - // return NULL; int instc0 = -1; switch (id) { case SN_BitwiseAnd: - instc0 = XBINOP_FORCEINT_and; + instc0 = XBINOP_FORCEINT_AND; break; case SN_BitwiseOr: - instc0 = XBINOP_FORCEINT_or; + instc0 = XBINOP_FORCEINT_OR; break; case SN_Xor: - instc0 = XBINOP_FORCEINT_xor; + instc0 = XBINOP_FORCEINT_XOR; break; default: g_assert_not_reached (); @@ -1530,7 +1528,7 @@ static SimdIntrinsic advsimd_methods [] = { {SN_AddScalar, OP_XBINOP_SCALAR, OP_IADD, None, None, OP_XBINOP_SCALAR, OP_FADD}, {SN_AddWideningLower, OP_ARM64_SADD, None, OP_ARM64_UADD}, {SN_AddWideningUpper, OP_ARM64_SADD2, None, OP_ARM64_UADD2}, - {SN_And, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_and}, + {SN_And, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_AND}, {SN_BitwiseClear, OP_ARM64_BIC}, {SN_BitwiseSelect, OP_ARM64_BSL}, {SN_Ceiling, OP_XOP_OVR_X_X, INTRINS_AARCH64_ADV_SIMD_FRINTP}, @@ -1733,8 +1731,8 @@ static SimdIntrinsic advsimd_methods [] = { {SN_NegateSaturateScalar, OP_XOP_OVR_SCALAR_X_X, INTRINS_AARCH64_ADV_SIMD_SQNEG}, {SN_NegateScalar, OP_ARM64_XNEG_SCALAR}, {SN_Not, OP_ARM64_MVN}, - {SN_Or, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_or}, - {SN_OrNot, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_ornot}, + {SN_Or, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_OR}, + {SN_OrNot, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_ORNOT}, {SN_PolynomialMultiply, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_PMUL}, {SN_PolynomialMultiplyWideningLower, OP_ARM64_PMULL}, {SN_PolynomialMultiplyWideningUpper, OP_ARM64_PMULL2}, @@ -1854,7 +1852,7 @@ static SimdIntrinsic advsimd_methods [] = { {SN_UnzipOdd, OP_ARM64_UZP2}, {SN_VectorTableLookup, OP_XOP_OVR_X_X_X, INTRINS_AARCH64_ADV_SIMD_TBL1}, {SN_VectorTableLookupExtension, OP_XOP_OVR_X_X_X_X, INTRINS_AARCH64_ADV_SIMD_TBX1}, - {SN_Xor, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_xor}, + {SN_Xor, OP_XBINOP_FORCEINT, XBINOP_FORCEINT_XOR}, {SN_ZeroExtendWideningLower, OP_ARM64_UXTL}, {SN_ZeroExtendWideningUpper, OP_ARM64_UXTL2}, {SN_ZipHigh, OP_ARM64_ZIP2}, From fe6f95c60e8402da5f0f16612745cd4b3afae823 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 23 Feb 2022 11:52:02 -0800 Subject: [PATCH 06/10] Add type checks for each method and refactor --- src/mono/mono/mini/simd-intrinsics.c | 75 ++++++++++++++++++---------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index a6b38d2ebbc70b..859054225161a2 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -666,26 +666,34 @@ is_create_from_half_vectors_overload (MonoMethodSignature *fsig) return mono_metadata_type_equal (fsig->params [0], fsig->params [1]); } +static gboolean +is_element_type_primitive (MonoType *vector_type) +{ + MonoType *element_type = get_vector_t_elem_type (vector_type); + if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (element_type)) + return FALSE; + return TRUE; +} + static MonoInst* emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { if (!COMPILE_LLVM (cfg)) return NULL; - MonoClass *klass = cmethod->klass; int id = lookup_intrins (sri_vector_methods, sizeof (sri_vector_methods), cmethod); if (id == -1) return NULL; if (!strcmp (m_class_get_name (cfg->method->klass), "Vector256")) return NULL; // TODO: Fix Vector256.WithUpper/WithLower - + + MonoClass *klass = cmethod->klass; MonoTypeEnum arg0_type = fsig->param_count > 0 ? get_underlying_type (fsig->params [0]) : MONO_TYPE_VOID; switch (id) { case SN_Abs: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->params [0])) return NULL; #ifdef TARGET_ARM64 switch (arg0_type) { @@ -704,16 +712,22 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_Add: + case SN_Divide: case SN_Max: case SN_Min: case SN_Multiply: case SN_Subtract: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + return NULL; int instc0 = -1; if (arg0_type == MONO_TYPE_R4 || arg0_type == MONO_TYPE_R8) { switch (id) { case SN_Add: instc0 = OP_FADD; break; + case SN_Divide: + instc0 = OP_FDIV; + break; case SN_Max: instc0 = OP_FMAX; break; @@ -734,6 +748,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_Add: instc0 = OP_IADD; break; + case SN_Divide: + return NULL; case SN_Max: instc0 = OP_IMAX; break; @@ -752,12 +768,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, instc0, arg0_type, fsig, args); } - case SN_Divide: { - if ((arg0_type != MONO_TYPE_R4) && (arg0_type != MONO_TYPE_R8)) - return NULL; - return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, OP_FDIV, arg0_type, fsig, args); - } case SN_AndNot: + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + return NULL; #ifdef TARGET_ARM64 return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_BIC, -1, arg0_type, fsig, args); #else @@ -766,6 +779,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_BitwiseAnd: case SN_BitwiseOr: case SN_Xor: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + return NULL; int instc0 = -1; switch (id) { case SN_BitwiseAnd: @@ -793,14 +808,14 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_AsUInt16: case SN_AsUInt32: case SN_AsUInt64: { - MonoType *ret_type = get_vector_t_elem_type (fsig->ret); - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (ret_type) || !MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) return NULL; return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1); } case SN_Ceiling: case SN_Floor: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + return NULL; #ifdef TARGET_ARM64 if ((arg0_type != MONO_TYPE_R4) && (arg0_type != MONO_TYPE_R8)) return NULL; @@ -811,6 +826,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_ConditionalSelect: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1]) || !is_element_type_primitive (fsig->params [2])) + return NULL; #ifdef TARGET_ARM64 return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_BSL, -1, arg0_type, fsig, args); #else @@ -818,6 +835,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_Create: { + if (!is_element_type_primitive (fsig->ret)) + return NULL; MonoType *etype = get_vector_t_elem_type (fsig->ret); if (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype)) return emit_simd_ins (cfg, klass, type_to_expand_op (etype), args [0]->dreg, -1); @@ -827,10 +846,16 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_vector_create_elementwise (cfg, fsig, fsig->ret, etype, args); break; } - case SN_CreateScalar: + case SN_CreateScalar: { + if (!is_element_type_primitive (fsig->ret)) + return NULL; return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR, -1, arg0_type, fsig, args); - case SN_CreateScalarUnsafe: + } + case SN_CreateScalarUnsafe: { + if (!is_element_type_primitive (fsig->ret)) + return NULL; return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR_UNSAFE, -1, arg0_type, fsig, args); + } case SN_Equals: case SN_EqualsAll: case SN_EqualsAny: { @@ -853,10 +878,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } } case SN_GetElement: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (etype)) - return NULL; int size = mono_class_value_size (arg_class, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); int elems = size / esize; @@ -867,8 +892,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_GetLower: case SN_GetUpper: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) return NULL; int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); @@ -920,25 +944,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_ToScalar: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->params [0])) return NULL; int extract_op = type_to_extract_op (arg0_type); return emit_simd_ins_for_sig (cfg, klass, extract_op, 0, arg0_type, fsig, args); } case SN_ToVector128: case SN_ToVector128Unsafe: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) - return NULL; + if (!is_element_type_primitive (fsig->params [0])) + return NULL; int op = id == SN_ToVector128 ? OP_XWIDEN : OP_XWIDEN_UNSAFE; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); } case SN_WithElement: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (etype)) - return NULL; int size = mono_class_value_size (arg_class, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); int elems = size / esize; @@ -952,8 +974,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_WithLower: case SN_WithUpper: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) return NULL; int op = id == SN_GetLower ? OP_XINSERT_LOWER : OP_XINSERT_UPPER; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); From 6275a69f34ee438d6cb84d9d278eb90aeba7542c Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Fri, 25 Feb 2022 07:50:01 -0800 Subject: [PATCH 07/10] Remove extra condition check --- src/mono/mono/mini/simd-intrinsics.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 859054225161a2..be42d6e9ddbce7 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -670,9 +670,7 @@ static gboolean is_element_type_primitive (MonoType *vector_type) { MonoType *element_type = get_vector_t_elem_type (vector_type); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (element_type)) - return FALSE; - return TRUE; + return MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (element_type); } static MonoInst* From 1c3d05c5ce120b7f5ccf1f58cdcd54ff3b51ba48 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Sat, 26 Feb 2022 11:33:51 -0800 Subject: [PATCH 08/10] Loose the type check for vector creation methods --- src/mono/mono/mini/simd-intrinsics.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index be42d6e9ddbce7..68a06fe65c5ec8 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -833,9 +833,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_Create: { - if (!is_element_type_primitive (fsig->ret)) - return NULL; MonoType *etype = get_vector_t_elem_type (fsig->ret); + if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) + return NULL; if (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype)) return emit_simd_ins (cfg, klass, type_to_expand_op (etype), args [0]->dreg, -1); else if (is_create_from_half_vectors_overload (fsig)) @@ -845,20 +845,21 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi break; } case SN_CreateScalar: { - if (!is_element_type_primitive (fsig->ret)) + MonoType *etype = get_vector_t_elem_type (fsig->ret); + if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) return NULL; return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR, -1, arg0_type, fsig, args); } case SN_CreateScalarUnsafe: { - if (!is_element_type_primitive (fsig->ret)) + MonoType *etype = get_vector_t_elem_type (fsig->ret); + if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) return NULL; return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR_UNSAFE, -1, arg0_type, fsig, args); } case SN_Equals: case SN_EqualsAll: case SN_EqualsAny: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) return NULL; switch (id) { @@ -899,8 +900,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_GreaterThanOrEqual: case SN_LessThan: case SN_LessThanOrEqual: { - MonoType *arg_type = get_vector_t_elem_type (fsig->params [0]); - if (!MONO_TYPE_IS_INTRINSICS_VECTOR_PRIMITIVE (arg_type)) + if (!is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) return NULL; gboolean is_unsigned = type_is_unsigned (fsig->params [0]); From 7c0aacacda61f0885f477ab23c52a61901a83c19 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Mon, 28 Feb 2022 05:59:01 -0800 Subject: [PATCH 09/10] Remove type checks for Create* functions --- src/mono/mono/mini/simd-intrinsics.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 68a06fe65c5ec8..f5b1f522d58eef 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -834,8 +834,6 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_Create: { MonoType *etype = get_vector_t_elem_type (fsig->ret); - if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) - return NULL; if (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype)) return emit_simd_ins (cfg, klass, type_to_expand_op (etype), args [0]->dreg, -1); else if (is_create_from_half_vectors_overload (fsig)) @@ -844,18 +842,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_vector_create_elementwise (cfg, fsig, fsig->ret, etype, args); break; } - case SN_CreateScalar: { - MonoType *etype = get_vector_t_elem_type (fsig->ret); - if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) - return NULL; + case SN_CreateScalar: return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR, -1, arg0_type, fsig, args); - } - case SN_CreateScalarUnsafe: { - MonoType *etype = get_vector_t_elem_type (fsig->ret); - if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) - return NULL; + case SN_CreateScalarUnsafe: return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR_UNSAFE, -1, arg0_type, fsig, args); - } case SN_Equals: case SN_EqualsAll: case SN_EqualsAny: { From 720a0dc356c6ee25715ddeb8640d8a16dc92996c Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Tue, 1 Mar 2022 20:35:01 -0800 Subject: [PATCH 10/10] Remove some of the type checks --- src/mono/mono/mini/simd-intrinsics.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index f5b1f522d58eef..f83be571941124 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -715,7 +715,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_Min: case SN_Multiply: case SN_Subtract: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; int instc0 = -1; if (arg0_type == MONO_TYPE_R4 || arg0_type == MONO_TYPE_R8) { @@ -767,7 +767,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_simd_ins_for_sig (cfg, klass, OP_XBINOP, instc0, arg0_type, fsig, args); } case SN_AndNot: - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; #ifdef TARGET_ARM64 return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_BIC, -1, arg0_type, fsig, args); @@ -777,7 +777,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_BitwiseAnd: case SN_BitwiseOr: case SN_Xor: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; int instc0 = -1; switch (id) { @@ -812,8 +812,6 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_Ceiling: case SN_Floor: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) - return NULL; #ifdef TARGET_ARM64 if ((arg0_type != MONO_TYPE_R4) && (arg0_type != MONO_TYPE_R8)) return NULL; @@ -824,7 +822,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_ConditionalSelect: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1]) || !is_element_type_primitive (fsig->params [2])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; #ifdef TARGET_ARM64 return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_BSL, -1, arg0_type, fsig, args); @@ -849,9 +847,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_Equals: case SN_EqualsAll: case SN_EqualsAny: { - if (!is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; - switch (id) { case SN_Equals: return emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); @@ -881,7 +878,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_GetLower: case SN_GetUpper: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); @@ -890,9 +887,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_GreaterThanOrEqual: case SN_LessThan: case SN_LessThanOrEqual: { - if (!is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; - gboolean is_unsigned = type_is_unsigned (fsig->params [0]); MonoInst *ins = emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); switch (id) { @@ -915,6 +911,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_Negate: case SN_OnesComplement: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; #ifdef TARGET_ARM64 int op = id == SN_Negate ? OP_ARM64_XNEG : OP_ARM64_MVN; return emit_simd_ins_for_sig (cfg, klass, op, -1, arg0_type, fsig, args); @@ -923,6 +921,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #endif } case SN_Sqrt: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; #ifdef TARGET_ARM64 if ((arg0_type != MONO_TYPE_R4) && (arg0_type != MONO_TYPE_R8)) return NULL; @@ -940,12 +940,12 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_ToVector128: case SN_ToVector128Unsafe: { if (!is_element_type_primitive (fsig->params [0])) - return NULL; + return NULL; int op = id == SN_ToVector128 ? OP_XWIDEN : OP_XWIDEN_UNSAFE; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args); } case SN_WithElement: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; @@ -962,7 +962,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } case SN_WithLower: case SN_WithUpper: { - if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + if (!is_element_type_primitive (fsig->params [0])) return NULL; int op = id == SN_GetLower ? OP_XINSERT_LOWER : OP_XINSERT_UPPER; return emit_simd_ins_for_sig (cfg, klass, op, 0, arg0_type, fsig, args);