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

Code before:
            break;
    }

    return result;
}

GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)
{
    noway_assert(call->gtCallType == CT_USER_FUNC);

    assert((m_compiler->info.compCompHnd->getMethodAttribs(call->gtCallMethHnd) &
            (CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL)) == (CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL));

    GenTree* thisArgNode;
    if (call->IsTailCallViaJitHelper())
    {
        thisArgNode = call->gtArgs.GetArgByIndex(0)->GetNode();
    }
    else
    {
        thisArgNode = call->gtArgs.GetThisArg()->GetNode();
    }

    assert(thisArgNode != nullptr);

#if HAS_FIXED_REGISTGER_SET
    assert(thisArgNode->OperIs(GT_PUTARG_REG));
    GenTree* thisExpr = thisArgNode->AsOp()->gtOp1;
#else
    GenTree* thisExpr = thisArgNode;
#endif

    // We're going to use the 'this' expression multiple times, so make a local to copy it.

    GenTree* base;
    if (thisExpr->OperIs(GT_LCL_VAR))
    {
        base = m_compiler->gtNewLclvNode(thisExpr->AsLclVar()->GetLclNum(), thisExpr->TypeGet());
    }
    else if (thisExpr->OperIs(GT_LCL_FLD))
    {
        base = m_compiler->gtNewLclFldNode(thisExpr->AsLclFld()->GetLclNum(), thisExpr->TypeGet(),
                                           thisExpr->AsLclFld()->GetLclOffs());
    }
    else
    {
        unsigned delegateInvokeTmp = m_compiler->lvaGrabTemp(true DEBUGARG("delegate invoke call"));
        base                       = m_compiler->gtNewLclvNode(delegateInvokeTmp, thisExpr->TypeGet());

#if HAS_FIXED_REGISTER_SET
        LIR::Use thisExprUse(BlockRange(), &thisArgNode->AsOp()->gtOp1, thisArgNode);

Review comment (bug):
Spelling error in preprocessor macro name: HAS_FIXED_REGISTGER_SET should be HAS_FIXED_REGISTER_SET. This typo causes the condition to always evaluate to false (undefined macros evaluate to 0), which means the code in the #else branch is always executed regardless of the target architecture. This could lead to incorrect behavior on architectures with fixed register sets where the assert and thisExpr assignment should be different.
```suggestion
#if HAS_FIXED_REGISTER_SET
```

Code after:
            break;
    }

    return result;
}

//----------------------------------------------------------------------------------------------
// LowerDelegateInvoke: lower a delegate invoke, accessing fields of the delegate
//
// Arguments:
//     call - call representing a delegate invoke.
//
// Return Value:
//    Control expr for the delegate invoke call, for further lowering.
//
GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)
{
    noway_assert(call->gtCallType == CT_USER_FUNC);

    assert((m_compiler->info.compCompHnd->getMethodAttribs(call->gtCallMethHnd) &
            (CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL)) == (CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL));

    CallArg* thisArg = nullptr;

    if (call->IsTailCallViaJitHelper())
    {
        thisArg = call->gtArgs.GetArgByIndex(0);
    }
    else
    {
        thisArg = call->gtArgs.GetThisArg();
    }

    assert(thisArg != nullptr);
    GenTree* thisArgNode = thisArg->GetNode();
    assert(thisArgNode != nullptr);

#if HAS_FIXED_REGISTER_SET
    assert(thisArgNode->OperIs(GT_PUTARG_REG));
    GenTree* thisExpr = thisArgNode->AsOp()->gtOp1;
    LIR::Use thisExprUse(BlockRange(), &thisArgNode->AsOp()->gtOp1, thisArgNode);
#else
    GenTree* thisExpr = thisArgNode;
    LIR::Use thisExprUse(BlockRange(), &thisArg->NodeRef(), call);
#endif

    // We're going to use the 'this' expression multiple times, so make a local to copy it.

    GenTree* base;
    if (thisExpr->OperIs(GT_LCL_VAR))
    {