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

Code before:
                    virtToPhysRegMap[static_cast<unsigned>(argType)].DeclaredCount--;
                }

                const ParameterRegisterLocalMapping* mapping =
                    m_compiler->FindParameterRegisterLocalMappingByRegister(argReg);
                if ((mapping != nullptr) && (m_compiler->lvaGetDesc(mapping->LclNum)->GetRegNum() == argReg))
                {
                    virtToPhysRegMap[static_cast<unsigned>(argType)].DeclaredCount--;
                }
            }
        }
    }
    for (WasmValueType type = WasmValueType::First; type < WasmValueType::Count; ++type)
    {
        PhysicalRegBank& physRegs = virtToPhysRegMap[static_cast<unsigned>(type)];
        physRegs.IndexBase        = indexBase;
        physRegs.Index            = indexBase;
        indexBase += physRegs.DeclaredCount;
    }

    auto allocPhysReg = [&](regNumber virtReg, LclVarDsc* varDsc) {
        regNumber physReg;
        if ((varDsc != nullptr) && varDsc->lvIsRegArg)
        {
            // If this is a struct passed as its field, find the parent local to get the correct ABI info.
            unsigned lclNum = varDsc->lvIsStructField ? varDsc->lvParentLcl : m_compiler->lvaGetLclNum(varDsc);
            const ABIPassingInformation& abiInfo = m_compiler->lvaGetParameterABIInfo(lclNum);
            assert(abiInfo.HasExactlyOneRegisterSegment());
            physReg = abiInfo.Segment(0).GetRegister();
        }
        else if ((varDsc != nullptr) && varDsc->lvIsParamRegTarget)
        {
            unsigned                             lclNum = m_compiler->lvaGetLclNum(varDsc);
            const ParameterRegisterLocalMapping* mapping =
                m_compiler->FindParameterRegisterLocalMappingByLocal(lclNum, 0);
            assert(mapping != nullptr);
            physReg = mapping->RegisterSegment->GetRegister();
        }
        else
        {
            WasmValueType type         = WasmRegToType(virtReg);
            unsigned      physRegIndex = virtToPhysRegMap[static_cast<unsigned>(type)].Index++;
            physReg                    = MakeWasmReg(physRegIndex, type);
        }

        assert(genIsValidReg(physReg));
        if ((varDsc != nullptr) && varDsc->lvIsRegCandidate())
        {
            if (varDsc->lvIsParam || varDsc->lvIsParamRegTarget)
            {
                // This is the register codegen will move the local from its ABI location in prolog.

Review comment (suggestion):
I think the right fix for this problem is to add `!varDsc->lvIsStructField` to the condition under which we are doing this. It will be covered by the `lvIsParamRegTarget` branch.


Code after:
                    virtToPhysRegMap[static_cast<unsigned>(argType)].DeclaredCount--;
                }

                const ParameterRegisterLocalMapping* mapping =
                    m_compiler->FindParameterRegisterLocalMappingByRegister(argReg);
                if ((mapping != nullptr) && (m_compiler->lvaGetDesc(mapping->LclNum)->GetRegNum() == argReg))
                {
                    virtToPhysRegMap[static_cast<unsigned>(argType)].DeclaredCount--;
                }
            }
        }
    }
    for (WasmValueType type = WasmValueType::First; type < WasmValueType::Count; ++type)
    {
        PhysicalRegBank& physRegs = virtToPhysRegMap[static_cast<unsigned>(type)];
        physRegs.IndexBase        = indexBase;
        physRegs.Index            = indexBase;
        indexBase += physRegs.DeclaredCount;
    }

    auto allocPhysReg = [&](regNumber virtReg, LclVarDsc* varDsc) {
        regNumber physReg;
        if ((varDsc != nullptr) && varDsc->lvIsRegArg && !varDsc->lvIsStructField)
        {
            unsigned                     lclNum  = m_compiler->lvaGetLclNum(varDsc);
            const ABIPassingInformation& abiInfo = m_compiler->lvaGetParameterABIInfo(lclNum);
            assert(abiInfo.HasExactlyOneRegisterSegment());
            physReg = abiInfo.Segment(0).GetRegister();
        }
        else if ((varDsc != nullptr) && varDsc->lvIsParamRegTarget)
        {
            unsigned                             lclNum = m_compiler->lvaGetLclNum(varDsc);
            const ParameterRegisterLocalMapping* mapping =
                m_compiler->FindParameterRegisterLocalMappingByLocal(lclNum, 0);
            assert(mapping != nullptr);
            physReg = mapping->RegisterSegment->GetRegister();
        }
        else
        {
            WasmValueType type         = WasmRegToType(virtReg);
            unsigned      physRegIndex = virtToPhysRegMap[static_cast<unsigned>(type)].Index++;
            physReg                    = MakeWasmReg(physRegIndex, type);
        }

        assert(genIsValidReg(physReg));
        if ((varDsc != nullptr) && varDsc->lvIsRegCandidate())
        {
            if (varDsc->lvIsParam || varDsc->lvIsParamRegTarget)
            {
                // This is the register codegen will move the local from its ABI location in prolog.
                varDsc->SetArgInitReg(physReg);