From 84b502d3e1d23447dd1293538b42925f92428a92 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Mon, 28 Jul 2025 13:49:42 -0700 Subject: [PATCH] JIT: enable inlining of IL stubs with EH Also, bail out of inlining analysis early if the pinvoke call was marked as unmanaged during initial pinvoke analysis. Closes #113742 --- src/coreclr/jit/importercalls.cpp | 20 ++++++++++++-------- src/coreclr/jit/inline.def | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 79581b183fc04c..80387355a6818d 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -7847,6 +7847,14 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, return; } + if (call->IsUnmanaged()) + { + // We must have IL to inline. + // + inlineResult->NoteFatal(InlineObservation::CALLEE_IS_UNMANAGED); + return; + } + // Inlining candidate determination needs to honor only IL tail prefix. // Inlining takes precedence over implicit tail call optimization (if the call is not directly recursive). if (call->IsTailPrefixedCall()) @@ -8028,6 +8036,10 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, if (methAttr & CORINFO_FLG_PINVOKE) { + // We should have already ruled out cases where we can directly call the unamanged method. + // + assert(!call->IsUnmanaged()); + if (!impCanPInvokeInlineCallSite(compCurBB)) { inlineResult->NoteFatal(InlineObservation::CALLSITE_PINVOKE_EH); @@ -8053,14 +8065,6 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, inlineResult->NoteFatal(InlineObservation::CALLSITE_IS_WITHIN_FILTER); return; } - - // Do not inline pinvoke stubs with EH. - // - if ((methAttr & CORINFO_FLG_PINVOKE) != 0) - { - inlineResult->NoteFatal(InlineObservation::CALLEE_HAS_EH); - return; - } } // The old value should be null OR this call should be a guarded devirtualization candidate. diff --git a/src/coreclr/jit/inline.def b/src/coreclr/jit/inline.def index 47a226e07d4116..2dfbccd20dc182 100644 --- a/src/coreclr/jit/inline.def +++ b/src/coreclr/jit/inline.def @@ -42,6 +42,7 @@ INLINE_OBSERVATION(IS_ARRAY_METHOD, bool, "is array method", INLINE_OBSERVATION(IS_JIT_NOINLINE, bool, "noinline per JitNoinline", FATAL, CALLEE) INLINE_OBSERVATION(IS_NOINLINE, bool, "noinline per IL/cached result", FATAL, CALLEE) INLINE_OBSERVATION(IS_SYNCHRONIZED, bool, "is synchronized", FATAL, CALLEE) +INLINE_OBSERVATION(IS_UNMANAGED, bool, "is unmanaged code", FATAL, CALLEE) INLINE_OBSERVATION(IS_VM_NOINLINE, bool, "noinline per VM", FATAL, CALLEE) INLINE_OBSERVATION(LACKS_RETURN, bool, "no return opcode", FATAL, CALLEE) INLINE_OBSERVATION(LDFLD_NEEDS_HELPER, bool, "ldfld needs helper", FATAL, CALLEE)