diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index fa52e9dd7521c..139dcfbbdd5b4 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -7607,6 +7607,8 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg) flags |= MONO_AOT_METHOD_FLAG_HAS_CTX; if (cfg->interp_entry_only) flags |= MONO_AOT_METHOD_FLAG_INTERP_ENTRY_ONLY; + if (cfg->uses_simd_intrinsics && cfg->compile_llvm) + flags |= MONO_AOT_METHOD_FLAG_HAS_LLVM_INTRINSICS; /* Saved into another table so it can be accessed without having access to this data */ cfg->aot_method_flags = flags; diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 113984590689b..11c8888d17b03 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4441,16 +4441,15 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint g_free (full_name); } - if (mono_llvm_only) { - guint8 flags = amodule->method_flags_table [method_index]; - /* The caller needs to looks this up, but its hard to do without constructing the full MonoJitInfo, so save it here */ - if (flags & (MONO_AOT_METHOD_FLAG_GSHAREDVT_VARIABLE | MONO_AOT_METHOD_FLAG_INTERP_ENTRY_ONLY)) { - mono_aot_lock (); - if (!code_to_method_flags) - code_to_method_flags = g_hash_table_new (NULL, NULL); - g_hash_table_insert (code_to_method_flags, code, GUINT_TO_POINTER (flags)); - mono_aot_unlock (); - } + guint8 flags = amodule->method_flags_table [method_index]; + /* The caller needs to looks this up, but its hard to do without constructing the full MonoJitInfo, so save it here */ + if ((mono_llvm_only && (flags & (MONO_AOT_METHOD_FLAG_GSHAREDVT_VARIABLE | MONO_AOT_METHOD_FLAG_INTERP_ENTRY_ONLY))) || + (flags & MONO_AOT_METHOD_FLAG_HAS_LLVM_INTRINSICS)) { + mono_aot_lock (); + if (!code_to_method_flags) + code_to_method_flags = g_hash_table_new (NULL, NULL); + g_hash_table_insert (code_to_method_flags, code, GUINT_TO_POINTER (flags)); + mono_aot_unlock (); } init_plt (amodule); @@ -6547,6 +6546,12 @@ mono_aot_get_method_flags (guint8 *code) return (MonoAotMethodFlags)flags; } +MonoAotFileFlags +mono_aot_get_module_flags (gpointer aot_module) +{ + return ((MonoAotModule*)aot_module)->info.flags; +} + #else /* AOT disabled */ @@ -6747,4 +6752,10 @@ mono_aot_get_method_flags (guint8 *code) return MONO_AOT_METHOD_FLAG_NONE; } +MonoAotFileFlags +mono_aot_get_module_flags (gpointer aot_module) +{ + return 0; +} + #endif diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index e4f84523c45e2..13690e31904d4 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -84,6 +84,7 @@ typedef enum { MONO_AOT_METHOD_FLAG_HAS_PATCHES = 4, MONO_AOT_METHOD_FLAG_HAS_CTX = 8, MONO_AOT_METHOD_FLAG_INTERP_ENTRY_ONLY = 16, + MONO_AOT_METHOD_FLAG_HAS_LLVM_INTRINSICS = 32, } MonoAotMethodFlags; #undef DEBUG_AOT_NAME_TABLE @@ -282,6 +283,7 @@ guint32 mono_aot_find_method_index (MonoMethod *method); gboolean mono_aot_init_llvm_method (gpointer aot_module, gpointer method_info, MonoClass *init_class, MonoError *error); GHashTable *mono_aot_get_weak_field_indexes (MonoImage *image); MonoAotMethodFlags mono_aot_get_method_flags (guint8 *code); +MonoAotFileFlags mono_aot_get_module_flags (gpointer aot_module); #ifdef MONO_ARCH_CODE_EXEC_ONLY typedef guint32 (*MonoAotResolvePltInfoOffset)(gpointer amodule, guint32 plt_entry_index); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 6734b2d0ce5c3..d9432fd5510de 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4179,6 +4179,20 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method) if (method_does_not_return (method)) return FALSE; + MonoAotModule *amodule = m_class_get_image (method->klass)->aot_module; + // If method is present in aot image compiled with llvm and it uses hw intrinsics we don't inline it, + // since we might not have support for those intrinsics with JIT + if (amodule && (amodule != AOT_MODULE_NOT_FOUND) && (mono_aot_get_module_flags (amodule) & MONO_AOT_FILE_FLAG_WITH_LLVM)) { + ERROR_DECL (error); + mono_class_init_internal (method->klass); + gpointer addr = mono_aot_get_method (method, error); + if (addr && is_ok (error)) { + MonoAotMethodFlags flags = mono_aot_get_method_flags (addr); + if (flags & MONO_AOT_METHOD_FLAG_HAS_LLVM_INTRINSICS) + return FALSE; + } + } + return TRUE; }