Skip to content

Commit

Permalink
[mono] Fix Vector<T>.IsSupported intrinsic (#90023)
Browse files Browse the repository at this point in the history
Fixes #88983
---------

Co-authored-by: Larry Ewing <lewing@microsoft.com>
  • Loading branch information
ivanpovazan and lewing authored Aug 14, 2023
1 parent 8323e58 commit 715086f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 60 deletions.
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 @@ -2410,8 +2410,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;

Expand All @@ -2428,9 +2428,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 @@ -2441,25 +2449,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

0 comments on commit 715086f

Please sign in to comment.