diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index dcc065e8303292..cad0331c7f309c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1903,6 +1903,12 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken) // Don't get async variant of Delegate.Invoke method; the pointed to method is not an async variant either. allowAsyncVariant = allowAsyncVariant && !method.OwningType.IsDelegate; + // Only use the async variant for runtime-async methods. For non-runtime-async Task-returning + // methods, the JIT will revert to the original method (via the getAsyncOtherVariant check for + // direct calls). Returning null here causes the JIT to treat this as a regular awaited call, + // which is the correct behavior and avoids unnecessary work. + allowAsyncVariant = allowAsyncVariant && method.IsAsync; + method = allowAsyncVariant ? _compilation.TypeSystemContext.GetAsyncVariantMethod(method) : null; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index a22040709eca7d..1c6e32e1efc838 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -486,6 +486,11 @@ private void ImportCall(ILOpcode opcode, int token) // Don't get async variant of Delegate.Invoke method; the pointed to method is not an async variant either. allowAsyncVariant = allowAsyncVariant && !method.OwningType.IsDelegate; + // Don't use the async variant for non-runtime-async methods. The JIT will revert to the original + // method in such cases (via the getAsyncOtherVariant check for direct calls), causing a mismatch + // between the precomputed generic dictionary entries and what the JIT looks up at compile time. + allowAsyncVariant = allowAsyncVariant && method.IsAsync; + if (allowAsyncVariant && MatchTaskAwaitPattern()) { runtimeDeterminedMethod = _factory.TypeSystemContext.GetAsyncVariantMethod(runtimeDeterminedMethod);