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

Code before:
//
void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
{
    assert(tree->OperIs(GT_STORE_LCL_VAR));

    if (tree->gtGetOp1()->IsMultiRegNode())
    {
        NYI_WASM("multi-reg GT_STORE_LCL_VAR");
    }

    LclVarDsc* varDsc = compiler->lvaGetDesc(tree);

    if (!varDsc->lvIsRegCandidate())
    {
        var_types type = varDsc->GetRegisterType(tree);
        // TODO-WASM: actually local.get the frame base local here.
        GetEmitter()->emitIns_S(ins_Store(type), emitTypeSize(tree), tree->GetLclNum(), 0);
        genProduceReg(tree);
    }
    else
    {
        assert(genIsValidReg(varDsc->GetRegNum()));
        unsigned wasmLclIndex = UnpackWasmReg(varDsc->GetRegNum());
        GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(tree), wasmLclIndex);
    }
}

//------------------------------------------------------------------------
// genCodeForCompare: Produce code for a GT_EQ/GT_NE/GT_LT/GT_LE/GT_GE/GT_GT node.
//
// Arguments:
//    tree - the node
//
void CodeGen::genCodeForCompare(GenTreeOp* tree)
{
    assert(tree->OperIsCmpCompare());

    GenTree* const  op1     = tree->gtGetOp1();
    var_types const op1Type = op1->TypeGet();

    if (varTypeIsFloating(op1Type))
    {
        genCompareFloat(tree);
    }
    else
    {
        genCompareInt(tree);
    }
}

//------------------------------------------------------------------------

Review comment (suggestion):
The operand of the store (op1) should be consumed before emitting the store instruction. All other architectures call `genConsumeRegs(op1)` (or similar) before processing the store. For example, see codegenxarch.cpp line 5337 and codegenarm.cpp line 1103.

Add:
```cpp
GenTree* op1 = tree->gtGetOp1();
genConsumeRegs(op1);
```

This should be added at the beginning of the function, after the multi-reg check.

Code after:
//
void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
{
    assert(tree->OperIs(GT_STORE_LCL_VAR));

    GenTree* const op1 = tree->gtGetOp1();
    assert(!op1->IsMultiRegNode());
    genConsumeRegs(op1);

    LclVarDsc* varDsc    = compiler->lvaGetDesc(tree);
    regNumber  targetReg = varDsc->GetRegNum();

    if (!varDsc->lvIsRegCandidate())
    {
        // TODO-WASM: handle these cases in lower/ra.
        // Emit drop for now to simulate the store effect on the wasm stack.
        GetEmitter()->emitIns(INS_drop);
        genUpdateLife(tree);
    }
    else
    {
        assert(genIsValidReg(targetReg));
        unsigned wasmLclIndex = UnpackWasmReg(targetReg);
        GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(tree), wasmLclIndex);
        genUpdateLifeStore(tree, targetReg, varDsc);
    }
}

//------------------------------------------------------------------------
// genCodeForCompare: Produce code for a GT_EQ/GT_NE/GT_LT/GT_LE/GT_GE/GT_GT node.
//
// Arguments:
//    tree - the node
//
void CodeGen::genCodeForCompare(GenTreeOp* tree)
{
    assert(tree->OperIsCmpCompare());

    GenTree* const  op1     = tree->gtGetOp1();
    var_types const op1Type = op1->TypeGet();

    if (varTypeIsFloating(op1Type))
    {
        genCompareFloat(tree);
    }
    else
    {
        genCompareInt(tree);
    }
}