From 5f640a083ea86d37161f28f1df14eb891e801bb4 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 4 Aug 2023 16:17:20 +0200 Subject: [PATCH 1/7] Fix Vector.IsSupported intrinsic --- src/mono/mono/mini/simd-intrinsics.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 4f05655f1fe26..e32650340c2b3 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2346,11 +2346,19 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MonoClass *klass = cmethod->klass; MonoType *etype = mono_class_get_context (klass)->class_inst->type_argv [0]; - gboolean supported = TRUE; + gboolean is_primitive_element_type = MONO_TYPE_IS_VECTOR_PRIMITIVE (etype); - if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) + // special case SN_get_IsSupported intrinsic which verifies whether a type parameter T is supported for a generic vector + if (id == SN_get_IsSupported) { + MonoInst *ins = NULL; + EMIT_NEW_ICONST (cfg, ins, is_primitive_element_type ? 1 : 0); + return ins; + } + + if (!is_primitive_element_type) return NULL; + gboolean supported = TRUE; int size = mono_class_value_size (klass, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); g_assert (size > 0); @@ -2383,16 +2391,6 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #endif #endif - switch (id) { - case SN_get_IsSupported: { - MonoInst *ins = NULL; - EMIT_NEW_ICONST (cfg, ins, supported ? 1 : 0); - return ins; - } - default: - break; - } - if (!supported) return NULL; From 024119f574267533ec90204ab0bc63c1e3f0c6cc Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 4 Aug 2023 16:06:25 -0500 Subject: [PATCH 2/7] Fix throw helper for intrinsics vector types --- src/mono/mono/mini/intrinsics.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index 0230105303a83..d5ef19b0e177d 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -2188,6 +2188,8 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign case MONO_TYPE_U8: case MONO_TYPE_R4: case MONO_TYPE_R8: + case MONO_TYPE_I: + case MONO_TYPE_U: MONO_INST_NEW (cfg, ins, OP_NOP); MONO_ADD_INS (cfg->cbb, ins); return ins; From 428f79e2d2a9208be54f79322a8b8e2b44e34ee1 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 4 Aug 2023 16:12:36 -0500 Subject: [PATCH 3/7] Make throw helpers use MONO_TYPE_IS_VECTOR_PRIMITIVE --- src/mono/mono/mini/intrinsics.c | 50 ++++----------------------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index d5ef19b0e177d..b1e5e76723147 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -2141,60 +2141,20 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign !strcmp ("System", cmethod_klass_name_space) && !strcmp ("ThrowHelper", cmethod_klass_name)) { - if (!strcmp ("ThrowForUnsupportedNumericsVectorBaseType", cmethod->name)) { + if (!strcmp ("ThrowForUnsupportedNumericsVectorBaseType", cmethod->name) || + !strcmp ("ThrowForUnsupportedIntrinsicsVector64BaseType", cmethod->name) || + !strcmp ("ThrowForUnsupportedIntrinsicsVector128BaseType", cmethod->name) || + !strcmp ("ThrowForUnsupportedIntrinsicsVector256BaseType", cmethod->name)) { /* The mono JIT can't optimize the body of this method away */ MonoGenericContext *ctx = mono_method_get_context (cmethod); g_assert (ctx); g_assert (ctx->method_inst); MonoType *t = ctx->method_inst->type_argv [0]; - switch (t->type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_I: - case MONO_TYPE_U: + if (MONO_TYPE_IS_VECTOR_PRIMITIVE (t)) { MONO_INST_NEW (cfg, ins, OP_NOP); MONO_ADD_INS (cfg->cbb, ins); return ins; - default: - break; - } - } - else if (!strcmp ("ThrowForUnsupportedIntrinsicsVector64BaseType", cmethod->name) || - !strcmp ("ThrowForUnsupportedIntrinsicsVector128BaseType", cmethod->name) || - !strcmp ("ThrowForUnsupportedIntrinsicsVector256BaseType", cmethod->name)) { - /* The mono JIT can't optimize the body of this method away */ - MonoGenericContext *ctx = mono_method_get_context (cmethod); - g_assert (ctx); - g_assert (ctx->method_inst); - - MonoType *t = ctx->method_inst->type_argv [0]; - switch (t->type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_I: - case MONO_TYPE_U: - MONO_INST_NEW (cfg, ins, OP_NOP); - MONO_ADD_INS (cfg->cbb, ins); - return ins; - default: - break; } } } From 481fd873282b80f967067a5e690d919de2934134 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Mon, 7 Aug 2023 12:12:23 +0200 Subject: [PATCH 4/7] Return NULL when intrinsic is not supported on a given platform --- src/mono/mono/mini/simd-intrinsics.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index e32650340c2b3..642a62bb60446 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2358,7 +2358,6 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign if (!is_primitive_element_type) return NULL; - gboolean supported = TRUE; int size = mono_class_value_size (klass, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); g_assert (size > 0); @@ -2374,7 +2373,7 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #if defined(TARGET_WASM) if (!COMPILE_LLVM (cfg)) - supported = FALSE; + return NULL; #endif // FIXME: Support Vector64 for mini JIT on arm64 @@ -2385,15 +2384,12 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #ifdef TARGET_AMD64 if (!COMPILE_LLVM (cfg) && (size != 16)) - supported = FALSE; + return NULL; #ifdef TARGET_WIN32 - supported = FALSE; + return NULL; #endif #endif - if (!supported) - return NULL; - switch (id) { case SN_get_Count: { MonoInst *ins = NULL; From 1193537069706110f9bac64e17dc999e140e37bb Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Sat, 12 Aug 2023 13:42:13 +0200 Subject: [PATCH 5/7] Revert "Return NULL when intrinsic is not supported on a given platform" This reverts commit 481fd873282b80f967067a5e690d919de2934134. --- src/mono/mono/mini/simd-intrinsics.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 642a62bb60446..e32650340c2b3 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2358,6 +2358,7 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign if (!is_primitive_element_type) return NULL; + gboolean supported = TRUE; int size = mono_class_value_size (klass, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); g_assert (size > 0); @@ -2373,7 +2374,7 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #if defined(TARGET_WASM) if (!COMPILE_LLVM (cfg)) - return NULL; + supported = FALSE; #endif // FIXME: Support Vector64 for mini JIT on arm64 @@ -2384,12 +2385,15 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #ifdef TARGET_AMD64 if (!COMPILE_LLVM (cfg) && (size != 16)) - return NULL; + supported = FALSE; #ifdef TARGET_WIN32 - return NULL; + supported = FALSE; #endif #endif + if (!supported) + return NULL; + switch (id) { case SN_get_Count: { MonoInst *ins = NULL; From a9f3ad001c7301f022f0a0e7f047cb044c6f6650 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Sat, 12 Aug 2023 13:42:24 +0200 Subject: [PATCH 6/7] Revert "Fix Vector.IsSupported intrinsic" This reverts commit 5f640a083ea86d37161f28f1df14eb891e801bb4. --- src/mono/mono/mini/simd-intrinsics.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index e32650340c2b3..4f05655f1fe26 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2346,19 +2346,11 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MonoClass *klass = cmethod->klass; MonoType *etype = mono_class_get_context (klass)->class_inst->type_argv [0]; - gboolean is_primitive_element_type = MONO_TYPE_IS_VECTOR_PRIMITIVE (etype); - - // special case SN_get_IsSupported intrinsic which verifies whether a type parameter T is supported for a generic vector - if (id == SN_get_IsSupported) { - MonoInst *ins = NULL; - EMIT_NEW_ICONST (cfg, ins, is_primitive_element_type ? 1 : 0); - return ins; - } + gboolean supported = TRUE; - if (!is_primitive_element_type) + if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) return NULL; - gboolean supported = TRUE; int size = mono_class_value_size (klass, NULL); int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); g_assert (size > 0); @@ -2391,6 +2383,16 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #endif #endif + switch (id) { + case SN_get_IsSupported: { + MonoInst *ins = NULL; + EMIT_NEW_ICONST (cfg, ins, supported ? 1 : 0); + return ins; + } + default: + break; + } + if (!supported) return NULL; From 4228ed4b6291c87e8647c33e7d193bae05dfb7ba Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Sat, 12 Aug 2023 13:59:31 +0200 Subject: [PATCH 7/7] Properly fix Vector.IsSupported intrinsic handling --- src/mono/mono/mini/simd-intrinsics.c | 29 ++++++++++++---------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 4f05655f1fe26..f59cdf6423cbb 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2346,8 +2346,8 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MonoClass *klass = cmethod->klass; MonoType *etype = mono_class_get_context (klass)->class_inst->type_argv [0]; - gboolean supported = TRUE; + // Apart from filtering out non-primitive types this also filters out shared generic instance types like: T_BYTE which cannot be intrinsified if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) return NULL; @@ -2364,9 +2364,17 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign g_free (name); } + // Special case SN_get_IsSupported intrinsic handling in this function which verifies whether a type parameter T is supported for a generic vector. + // As we got passed the MONO_TYPE_IS_VECTOR_PRIMITIVE check above, this should always return true for primitive types. + if (id == SN_get_IsSupported) { + MonoInst *ins = NULL; + EMIT_NEW_ICONST (cfg, ins, 1); + return ins; + } + #if defined(TARGET_WASM) if (!COMPILE_LLVM (cfg)) - supported = FALSE; + return NULL; #endif // FIXME: Support Vector64 for mini JIT on arm64 @@ -2377,25 +2385,12 @@ emit_vector64_vector128_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #ifdef TARGET_AMD64 if (!COMPILE_LLVM (cfg) && (size != 16)) - supported = FALSE; + return NULL; #ifdef TARGET_WIN32 - supported = FALSE; + return NULL; #endif #endif - switch (id) { - case SN_get_IsSupported: { - MonoInst *ins = NULL; - EMIT_NEW_ICONST (cfg, ins, supported ? 1 : 0); - return ins; - } - default: - break; - } - - if (!supported) - return NULL; - switch (id) { case SN_get_Count: { MonoInst *ins = NULL;