Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Fix Vector<T>.IsSupported intrinsic #90023

Merged
merged 7 commits into from
Aug 14, 2023
Merged
48 changes: 5 additions & 43 deletions src/mono/mono/mini/intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -2141,58 +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:
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:
if (MONO_TYPE_IS_VECTOR_PRIMITIVE (t)) {
MONO_INST_NEW (cfg, ins, OP_NOP);
MONO_ADD_INS (cfg->cbb, ins);
return ins;
default:
break;
}
}
}
Expand Down
29 changes: 12 additions & 17 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
return NULL;

Expand All @@ -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
Expand All @@ -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;
Expand Down
Loading