Repository: dotnet/runtime
File: src/coreclr/jit/lowerwasm.cpp (C++)

Code before:

//------------------------------------------------------------------------
// LowerBlockStore: Lower a block store node
//
// Arguments:
//    blkNode - The block store node to lower
//
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
    GenTree* dstAddr = blkNode->Addr();
    GenTree* src     = blkNode->Data();
    unsigned size    = blkNode->Size();

    if (blkNode->OperIsInitBlkOp())
    {
        if (src->OperIs(GT_INIT_VAL))
        {
            src->SetContained();
            src = src->AsUnOp()->gtGetOp1();
        }

        if (blkNode->IsZeroingGcPointersOnHeap())
        {
            blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
            src->SetContained();
            // memory.fill
        }
        else
        {
            // memory.fill
        }
    }
    else
    {
        assert(src->OperIs(GT_IND, GT_LCL_VAR, GT_LCL_FLD));
        src->SetContained();

        if (src->OperIs(GT_LCL_VAR))
        {
            // TODO-1stClassStructs: for now we can't work with STORE_BLOCK source in register.
            // TODO-WASM: Is this true for wasm as well?
            const unsigned srcLclNum = src->AsLclVar()->GetLclNum();
            comp->lvaSetVarDoNotEnregister(srcLclNum DEBUGARG(DoNotEnregisterReason::BlockOp));
        }

        ClassLayout* layout               = blkNode->GetLayout();
        bool         doCpObj              = layout->HasGCPtr();
        unsigned     copyBlockUnrollLimit = comp->getUnrollThreshold(Compiler::UnrollKind::Memcpy);

        // CopyObj or CopyBlk
        if (doCpObj)

Review comment (suggestion):
in this case it's expected to emit a loop of pointer-sized stores (with 0 value) to guarantee atomicity for gc slots (which `memset` does not guarantee), I am not sure it's a problem today for WASM, but it's probably better to maintain that

Code after:

//------------------------------------------------------------------------
// LowerDivOrMod: Lowers a GT_[U]DIV/GT_[U]MOD node.
//
// Mark operands that need multiple uses for exception-inducing checks.
//
// Arguments:
//    divMod - the node to be lowered
//
void Lowering::LowerDivOrMod(GenTreeOp* divMod)
{
    ExceptionSetFlags exSetFlags = divMod->OperExceptions(m_compiler);
    if ((exSetFlags & ExceptionSetFlags::ArithmeticException) != ExceptionSetFlags::None)
    {
        divMod->gtGetOp1()->gtLIRFlags |= LIR::Flags::MultiplyUsed;
        divMod->gtGetOp2()->gtLIRFlags |= LIR::Flags::MultiplyUsed;
    }
    else if ((exSetFlags & ExceptionSetFlags::DivideByZeroException) != ExceptionSetFlags::None)
    {
        divMod->gtGetOp2()->gtLIRFlags |= LIR::Flags::MultiplyUsed;
    }

    ContainCheckDivOrMod(divMod);
}

//------------------------------------------------------------------------
// LowerBlockStore: Lower a block store node
//
// Arguments:
//    blkNode - The block store node to lower
//
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
    GenTree* dstAddr = blkNode->Addr();
    GenTree* src     = blkNode->Data();

    if (blkNode->OperIsInitBlkOp())
    {
        if (src->OperIs(GT_INIT_VAL))
        {
            src->SetContained();
            src = src->AsUnOp()->gtGetOp1();
        }

        if (blkNode->IsZeroingGcPointersOnHeap())
        {
            blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
            src->SetContained();
        }
        else
        {