diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index fce4152d0a0620..751b11fc8898ee 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -1139,6 +1139,25 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack* parent canLclVarEscapeViaParentStack = !Compiler::s_helperCallProperties.IsNoEscape(comp->eeGetHelperNum(asCall->gtCallMethHnd)); } + else if (asCall->IsSpecialIntrinsic()) + { + // Some known special intrinsics don't escape. At this moment, only the ones accepting byrefs + // are supported. In order to support more intrinsics accepting objects, we need extra work + // on the VM side which is not ready for that yet. + // + switch (comp->lookupNamedIntrinsic(asCall->gtCallMethHnd)) + { + case NI_System_SpanHelpers_ClearWithoutReferences: + case NI_System_SpanHelpers_Fill: + case NI_System_SpanHelpers_Memmove: + case NI_System_SpanHelpers_SequenceEqual: + canLclVarEscapeViaParentStack = false; + break; + + default: + break; + } + } // Note there is nothing special here about the parent being a call. We could move all this processing // up to the caller and handle any sort of tree that could lead to escapes this way. diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index b308408a47e5d5..92fceee7a37376 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1669,6 +1669,13 @@ void HelperCallProperties::init() isPure = true; break; + case CORINFO_HELP_MEMCPY: + case CORINFO_HELP_MEMZERO: + case CORINFO_HELP_MEMSET: + case CORINFO_HELP_NATIVE_MEMSET: + isNoEscape = true; + break; + case CORINFO_HELP_LDELEMA_REF: isPure = true; break;