diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 94d6bc8c01ac99..f18e96a335c045 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -2815,14 +2815,22 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) CopyBlockUnrollHelper helper(srcOffset, dstOffset, size); regNumber srcReg = srcAddrBaseReg; +#ifdef DEBUG + bool isSrcRegAddrAlignmentKnown = false; + bool isDstRegAddrAlignmentKnown = false; +#endif + if (srcLclNum != BAD_VAR_NUM) { bool fpBased; const int baseAddr = compiler->lvaFrameAddress(srcLclNum, &fpBased); srcReg = fpBased ? REG_FPBASE : REG_SPBASE; - helper.SetSrcOffset(baseAddr + srcOffset); + +#ifdef DEBUG + isSrcRegAddrAlignmentKnown = true; +#endif } regNumber dstReg = dstAddrBaseReg; @@ -2833,8 +2841,11 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) const int baseAddr = compiler->lvaFrameAddress(dstLclNum, &fpBased); dstReg = fpBased ? REG_FPBASE : REG_SPBASE; - helper.SetDstOffset(baseAddr + dstOffset); + +#ifdef DEBUG + isDstRegAddrAlignmentKnown = true; +#endif } bool canEncodeAllLoads = true; @@ -2948,6 +2959,18 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) } #endif +#ifndef JIT32_GCENCODER + if (!node->gtBlkOpGcUnsafe && ((srcOffsetAdjustment != 0) || (dstOffsetAdjustment != 0))) + { + // If node is not already marked as non-interruptible, and if are about to generate code + // that produce GC references in temporary registers not reported, then mark the block + // as non-interruptible. + // Corresponding EnableGC() will be done by the caller of this method. + node->gtBlkOpGcUnsafe = true; + GetEmitter()->emitDisableGC(); + } +#endif + if ((srcOffsetAdjustment != 0) && (dstOffsetAdjustment != 0)) { const regNumber tempReg1 = node->ExtractTempReg(RBM_ALLINT); diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index b6e06898b644e6..bc9f190d413fc3 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -440,18 +440,10 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (blkNode->OperIs(GT_STORE_OBJ)) { - if (!blkNode->AsObj()->GetLayout()->HasGCPtr()) + if (!blkNode->AsObj()->GetLayout()->HasGCPtr() || (isDstAddrLocal && (size <= copyBlockUnrollLimit))) { blkNode->SetOper(GT_STORE_BLK); } - else if (isDstAddrLocal && (size <= copyBlockUnrollLimit)) - { - // If the size is small enough to unroll then we need to mark the block as non-interruptible - // to actually allow unrolling. The generated code does not report GC references loaded in the - // temporary register(s) used for copying. - blkNode->SetOper(GT_STORE_BLK); - blkNode->gtBlkOpGcUnsafe = true; - } } if (blkNode->OperIs(GT_STORE_OBJ))