From 87789383afb40b302a9e1a9f4bcecaba7f487b3f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 2 Jul 2024 10:25:51 -0700 Subject: [PATCH 1/3] Add support for other same size vector bitcasts to Mono --- src/mono/mono/mini/interp/simd-methods.def | 5 +++++ src/mono/mono/mini/interp/transform-simd.c | 26 ++++++++++++++++++++++ src/mono/mono/mini/simd-intrinsics.c | 24 ++++++++++++++++++++ src/mono/mono/mini/simd-methods.h | 3 +++ 4 files changed, 58 insertions(+) diff --git a/src/mono/mono/mini/interp/simd-methods.def b/src/mono/mono/mini/interp/simd-methods.def index 6256c4ebca75c..a919c585114ed 100644 --- a/src/mono/mono/mini/interp/simd-methods.def +++ b/src/mono/mono/mini/interp/simd-methods.def @@ -31,11 +31,16 @@ SIMD_METHOD(AsInt32) SIMD_METHOD(AsInt64) SIMD_METHOD(AsNInt) SIMD_METHOD(AsNUInt) +SIMD_METHOD(AsPlane) +SIMD_METHOD(AsQuaternion) SIMD_METHOD(AsSByte) SIMD_METHOD(AsSingle) SIMD_METHOD(AsUInt16) SIMD_METHOD(AsUInt32) SIMD_METHOD(AsUInt64) +SIMD_METHOD(AsVector) +SIMD_METHOD(AsVector4) +SIMD_METHOD(AsVector128) SIMD_METHOD(ConditionalSelect) SIMD_METHOD(Create) SIMD_METHOD(CreateScalar) diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index 79f9e0c2970b5..fcd39d16847be 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -64,11 +64,16 @@ static guint16 sri_vector128_methods [] = { SN_AsInt64, SN_AsNInt, SN_AsNUInt, + SN_AsPlane, + SN_AsQuaternion, SN_AsSByte, SN_AsSingle, SN_AsUInt16, SN_AsUInt32, SN_AsUInt64, + SN_AsVector, + SN_AsVector4, + SN_AsVector128, SN_ConditionalSelect, SN_Create, SN_CreateScalar, @@ -444,6 +449,8 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature case SN_AsInt64: case SN_AsNInt: case SN_AsNUInt: + case SN_AsPlane: + case SN_AsQuaternion: case SN_AsSByte: case SN_AsSingle: case SN_AsUInt16: @@ -455,6 +462,25 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST; break; } + case SN_AsVector: + case SN_AsVector128: + case SN_AsVector4: { + if (!is_element_type_primitive (csignature->ret) || !is_element_type_primitive (csignature->params [0])) + return FALSE; + + MonoClass *ret_class = mono_class_from_mono_type_internal (csignature->ret); + int ret_size = mono_class_value_size (ret_class, NULL); + + MonoClass *arg_class = mono_class_from_mono_type_internal (csignature->params [0]); + int arg_size = mono_class_value_size (arg_class, NULL); + + if (arg_size == ret_size) { + simd_opcode = MINT_SIMD_INTRINS_P_P; + simd_intrins = INTERP_SIMD_INTRINSIC_V128_BITCAST; + break; + } + return FALSE; + } case SN_ConditionalSelect: simd_opcode = MINT_SIMD_INTRINS_P_PPP; simd_intrins = INTERP_SIMD_INTRINSIC_V128_CONDITIONAL_SELECT; diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 4bbc0a09e0869..bcd4ae0639e92 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -1187,11 +1187,16 @@ static guint16 sri_vector_methods [] = { SN_AsInt64, SN_AsNInt, SN_AsNUInt, + SN_AsPlane, + SN_AsQuaternion, SN_AsSByte, SN_AsSingle, SN_AsUInt16, SN_AsUInt32, SN_AsUInt64, + SN_AsVector, + SN_AsVector128, + SN_AsVector4, SN_BitwiseAnd, SN_BitwiseOr, SN_Ceiling, @@ -1622,6 +1627,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_AsInt64: case SN_AsNInt: case SN_AsNUInt: + case SN_AsPlane: + case SN_AsQuaternion: case SN_AsSByte: case SN_AsSingle: case SN_AsUInt16: @@ -1631,6 +1638,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1); } + case SN_AsVector: + case SN_AsVector128: + case SN_AsVector4: { + if (!is_element_type_primitive (fsig->ret) || !is_element_type_primitive (fsig->params [0])) + return NULL; + + MonoClass *ret_class = mono_class_from_mono_type_internal (fsig->ret); + int ret_size = mono_class_value_size (ret_class, NULL); + + MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + int arg_size = mono_class_value_size (arg_class, NULL); + + if (arg_size == ret_size) + return emit_simd_ins (cfg, klass, OP_XCAST, args [0]->dreg, -1); + + return NULL; + } case SN_Ceiling: case SN_Floor: { if (!type_enum_is_float (arg0_type)) diff --git a/src/mono/mono/mini/simd-methods.h b/src/mono/mono/mini/simd-methods.h index fbf4098406819..071da07c9e5bf 100644 --- a/src/mono/mono/mini/simd-methods.h +++ b/src/mono/mono/mini/simd-methods.h @@ -73,11 +73,14 @@ METHOD(AsInt32) METHOD(AsInt64) METHOD(AsNInt) METHOD(AsNUInt) +METHOD(AsPlane) +METHOD(AsQuaternion) METHOD(AsSByte) METHOD(AsSingle) METHOD(AsUInt16) METHOD(AsUInt32) METHOD(AsUInt64) +METHOD(AsVector) METHOD(AsVector128) METHOD(AsVector2) METHOD(AsVector256) From 6713a79d133ac14077d36144c692c10a67f6dc6e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 2 Jul 2024 19:18:48 -0700 Subject: [PATCH 2/3] Ensure get_common_simd_info handles non-generic input parameters --- src/mono/mono/mini/interp/transform-simd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index fcd39d16847be..39bebbdfdab5a 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -303,8 +303,14 @@ emit_common_simd_operations (TransformData *td, int id, int atype, int vector_si static gboolean get_common_simd_info (MonoClass *vector_klass, MonoMethodSignature *csignature, MonoTypeEnum *atype, int *vector_size, int *arg_size, int *scalar_arg) { - if (!m_class_is_simd_type (vector_klass) && csignature->param_count) - vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); + if (!m_class_is_simd_type (vector_klass) && csignature->param_count) { + if (csignature->params [0]->type == MONO_TYPE_GENERICINST) { + vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); + } else { + g_assert(csignature->ret->type == MONO_TYPE_GENERICINST); + vector_klass = mono_class_from_mono_type_internal (csignature->ret); + } + } if (!m_class_is_simd_type (vector_klass)) return FALSE; From 1e389dce40c51d930cbe7347d656f2f855ef8842 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 2 Jul 2024 22:18:48 -0700 Subject: [PATCH 3/3] Ensure emit_sri_vector128 correctly checks for the generic type argument --- src/mono/mono/mini/interp/transform-simd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index 39bebbdfdab5a..2b64baff7f44a 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -303,14 +303,8 @@ emit_common_simd_operations (TransformData *td, int id, int atype, int vector_si static gboolean get_common_simd_info (MonoClass *vector_klass, MonoMethodSignature *csignature, MonoTypeEnum *atype, int *vector_size, int *arg_size, int *scalar_arg) { - if (!m_class_is_simd_type (vector_klass) && csignature->param_count) { - if (csignature->params [0]->type == MONO_TYPE_GENERICINST) { - vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); - } else { - g_assert(csignature->ret->type == MONO_TYPE_GENERICINST); - vector_klass = mono_class_from_mono_type_internal (csignature->ret); - } - } + if (!m_class_is_simd_type (vector_klass) && csignature->param_count) + vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); if (!m_class_is_simd_type (vector_klass)) return FALSE; @@ -435,7 +429,13 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature gint16 simd_opcode = -1; gint16 simd_intrins = -1; - vector_klass = mono_class_from_mono_type_internal (csignature->ret); + if (csignature->ret->type == MONO_TYPE_GENERICINST) { + vector_klass = mono_class_from_mono_type_internal (csignature->ret); + } else if (csignature->params [0]->type == MONO_TYPE_GENERICINST) { + vector_klass = mono_class_from_mono_type_internal (csignature->params [0]); + } else { + return FALSE; + } MonoTypeEnum atype; int arg_size, scalar_arg;