From: Jakob Botsch Nielsen Date: Mon, 15 May 2023 21:56:53 +0000 (+0200) Subject: JIT: Fix new helper calls for some block copies involving promoted locals (#86246) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~2217 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=31658c683e225446c0b45e4c13bded81469cb26d;p=platform%2Fupstream%2Fdotnet%2Fruntime.git JIT: Fix new helper calls for some block copies involving promoted locals (#86246) The change in #85620 was missing a check for the case where the destination is not on stack but the source is. The backend still uses a helper call for this case. The field-by-field case would also usually involve helper calls since it would normally need write barriers; however, the exception were for byref fields, so Span/ReadOnlySpan were particularly affected. --- diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index fca0c73..329e9c1 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -830,10 +830,13 @@ void MorphCopyBlockHelper::MorphStructCases() // A simple heuristic when field by field copy is preferred: // - if fields can be enregistered; // - if the struct has only one field. + // - if the copy involves GC pointers and the destination isn't stack (backend uses a helper for these block + // copies) bool dstFldIsProfitable = ((m_dstVarDsc != nullptr) && (!m_dstVarDsc->lvDoNotEnregister || (m_dstVarDsc->lvFieldCnt == 1))); - bool srcFldIsProfitable = - ((m_srcVarDsc != nullptr) && (!m_srcVarDsc->lvDoNotEnregister || (m_srcVarDsc->lvFieldCnt == 1))); + bool srcFldIsProfitable = ((m_srcVarDsc != nullptr) && (!m_srcVarDsc->lvDoNotEnregister || + (m_srcVarDsc->HasGCPtr() && (m_dstVarDsc == nullptr)) || + (m_srcVarDsc->lvFieldCnt == 1))); // Are both dest and src promoted structs? if (m_dstDoFldAsg && m_srcDoFldAsg && (dstFldIsProfitable || srcFldIsProfitable)) {