diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 261968ae7f8f3..94089d1018d8d 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -2576,17 +2576,26 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
@@ -2597,7 +2606,8 @@
-
+
+
diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
index 49c5d60271171..1c085ed36e446 100644
--- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -151,6 +151,8 @@
+
+
diff --git a/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.Vectors.xml b/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.Vectors.xml
new file mode 100644
index 0000000000000..c50829b784392
--- /dev/null
+++ b/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.Vectors.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.x86.xml b/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.x86.xml
new file mode 100644
index 0000000000000..bd008db96ba1d
--- /dev/null
+++ b/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Intrinsics.x86.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c
index f8275230e210b..d8f80b0bc6a93 100644
--- a/src/mono/mono/mini/aot-compiler.c
+++ b/src/mono/mono/mini/aot-compiler.c
@@ -14229,7 +14229,7 @@ static void
acfg_free (MonoAotCompile *acfg)
{
#ifdef ENABLE_LLVM
- if (acfg->aot_opts.llvm)
+ if (mono_use_llvm || acfg->aot_opts.llvm)
mono_llvm_free_aot_module ();
#endif
diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c
index 87b9498074ce0..86c4eb2915874 100644
--- a/src/mono/mono/mini/method-to-ir.c
+++ b/src/mono/mono/mini/method-to-ir.c
@@ -4746,6 +4746,15 @@ mini_inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *
return inline_method (cfg, cmethod, fsig, sp, ip, real_offset, inline_always, NULL);
}
+static gboolean
+aggressive_inline_method (MonoMethod *cmethod)
+{
+ gboolean aggressive_inline = m_method_is_aggressive_inlining (cmethod);
+ if (aggressive_inline)
+ aggressive_inline = !mono_simd_unsupported_aggressive_inline_intrinsic_type (cmethod);
+ return aggressive_inline;
+}
+
/*
* inline_method:
*
@@ -4871,7 +4880,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
cfg->disable_inline = prev_disable_inline;
cfg->inline_depth --;
- if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))) {
+ if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && aggressive_inline_method (cmethod))) {
if (cfg->verbose_level > 2)
printf ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h
index 7a9ca5644678a..9982afc22e3f2 100644
--- a/src/mono/mono/mini/mini.h
+++ b/src/mono/mono/mini/mini.h
@@ -2962,6 +2962,7 @@ MonoInst* mono_emit_common_intrinsics (MonoCompile *cfg, MonoMethod *cmethod,
MonoInst* mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
MonoInst* mono_emit_simd_field_load (MonoCompile *cfg, MonoClassField *field, MonoInst *addr);
void mono_simd_intrinsics_init (void);
+gboolean mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod *cmethod);
MonoMethod*
mini_method_to_shared (MonoMethod *method); // null if not shared
diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c
index 13d341f9e8bf0..73e5d88f3b504 100644
--- a/src/mono/mono/mini/simd-intrinsics.c
+++ b/src/mono/mono/mini/simd-intrinsics.c
@@ -1178,6 +1178,20 @@ create_class_instance (const char* name_space, const char *name, MonoType *param
return ivector_inst;
}
+static gboolean
+is_supported_vector_primitive_type (MonoType *type)
+{
+ gboolean constrained_generic_param = (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
+
+ if (constrained_generic_param && type->data.generic_param->gshared_constraint && MONO_TYPE_IS_VECTOR_PRIMITIVE (type->data.generic_param->gshared_constraint))
+ return TRUE;
+
+ if (MONO_TYPE_IS_VECTOR_PRIMITIVE (type))
+ return TRUE;
+
+ return FALSE;
+}
+
static guint16 sri_vector_methods [] = {
SN_Abs,
SN_Add,
@@ -1423,8 +1437,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
return NULL;
if (vector_size == 256 || vector_size == 512)
- return NULL;
-
+ return NULL;
+
// FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64
#ifdef TARGET_ARM64
if (!COMPILE_LLVM (cfg)) {
@@ -2477,6 +2491,12 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
g_free (name);
}
+ if (id == SN_get_IsSupported) {
+ MonoInst *ins;
+ EMIT_NEW_ICONST (cfg, ins, is_supported_vector_primitive_type (etype) ? 1 : 0);
+ return ins;
+ }
+
// 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)) {
// Happens often in gshared code
@@ -3199,6 +3219,11 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
type = m_class_get_byval_arg (klass);
etype = mono_class_get_context (klass)->class_inst->type_argv [0];
+ if (id == SN_get_IsSupported) {
+ EMIT_NEW_ICONST (cfg, ins, is_supported_vector_primitive_type (etype) ? 1 : 0);
+ return ins;
+ }
+
if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype))
return NULL;
@@ -6118,11 +6143,37 @@ mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *i
decompose_vtype_opt_store_arg (cfg, bb, ins, &(ins->dreg));
}
}
+
+gboolean
+mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod *cmethod)
+{
+ /*
+ * If a method has been marked with aggressive inlining, check if we support
+ * aggressive inlining of the intrinsics type, if not, ignore aggressive inlining
+ * since it could end up inlining a large amount of code that most likely will end
+ * up as dead code.
+ */
+ if (!strcmp (m_class_get_name_space (cmethod->klass), "System.Runtime.Intrinsics")) {
+ if (!strncmp(m_class_get_name (cmethod->klass), "Vector", 6)) {
+ const char *vector_type = m_class_get_name (cmethod->klass) + 6;
+ if (!strcmp(vector_type, "256`1") || !strcmp(vector_type, "512`1"))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
#else
void
mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins)
{
}
+
+gboolean
+mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod* cmethod)
+{
+ return FALSE;
+}
+
#endif /*defined(TARGET_WIN32) && defined(TARGET_AMD64)*/
#endif /* DISABLE_JIT */
@@ -6157,6 +6208,12 @@ mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *i
{
}
+gboolean
+mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod* cmethod)
+{
+ return FALSE;
+}
+
#endif /* MONO_ARCH_SIMD_INTRINSICS */
#if defined(TARGET_AMD64)