Skip to content

[clr-interp] Emit INTOP_NEWMDARR only for array ctor #116544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

kotlarmilos
Copy link
Member

Description

This PR improves condition to emit INTOP_NEWMDARR only for array ctor and use rank as dimension count.

Fixes #116493

@Copilot Copilot AI review requested due to automatic review settings June 11, 2025 16:41
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

The PR improves the interpreter logic to ensure that INTOP_NEWMDARR is only emitted for array constructors, using the array rank as the dimension count rather than the original approach.

  • Removed fetching of method signature and constructor class.
  • Now retrieves the array class handle and its rank, and validates the constructor call accordingly.
Comments suppressed due to low confidence (1)

src/coreclr/interpreter/compiler.cpp:2514

  • Consider adding a brief comment above this conditional block explaining that the rank value is used as the expected number of constructor arguments for multi-dimensional arrays, which would improve clarity and maintainability.
if (callInfo.sig.retType == CORINFO_TYPE_VOID && callInfo.sig.numArgs == rank && (m_compHnd->getMethodAttribs(resolvedCallToken.hMethod) & CORINFO_FLG_CONSTRUCTOR) != 0)

@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 11, 2025
@kotlarmilos kotlarmilos added area-CodeGen-Interpreter-coreclr and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jun 11, 2025
@kotlarmilos kotlarmilos added this to the 10.0.0 milestone Jun 11, 2025
Copy link
Contributor

Tagging subscribers to this area: @BrzVlad, @janvorli, @kg
See info in area-owners.md if you want to be subscribed.

@@ -2508,15 +2508,15 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* constrainedClass, bool rea
}
else if ((callInfo.classFlags & CORINFO_FLG_ARRAY) && !readonly)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else if ((callInfo.classFlags & CORINFO_FLG_ARRAY) && !readonly)
else if (callInfo.classFlags & CORINFO_FLG_ARRAY)

!readonly should not be needed here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, you can check for newobj opcode and then you do not need the condition below:

if ((callInfo.classFlags & CORINFO_FLG_ARRAY) && newObj)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(It is what RuyJIT does - look for impImportNewObjArray.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

AddIns(INTOP_NEWMDARR);
m_pLastNewIns->data[0] = GetDataItemIndex(ctorClass);
m_pLastNewIns->data[1] = numArgs;
if (callInfo.sig.retType == CORINFO_TYPE_VOID && callInfo.sig.numArgs == rank && (m_compHnd->getMethodAttribs(resolvedCallToken.hMethod) & CORINFO_FLG_CONSTRUCTOR) != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callInfo.sig.numArgs == rank condition is not 100% right. The multi-dimm array constructors can take rank or rank * 2 arguments.

The overload that takes rank * 2 arguments is not expressible in C#. It allows you to specify lower bounds.

BrzVlad
BrzVlad previously approved these changes Jun 12, 2025
m_pLastNewIns->data[0] = GetDataItemIndex(ctorClass);
m_pLastNewIns->data[1] = numArgs;
m_pLastNewIns->data[0] = GetDataItemIndex(arrayClsHnd);
m_pLastNewIns->data[1] = rank;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be rank. This should be the actual number of the arguments in the signature, so that the code handles different overloads of array constructor correctly. The earlier code looks correct, the new code looks wrong. I think this part of the change should be reverted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you can rename the argument name on the executor side to numArgs to avoid confusion

static OBJECTREF CreateMultiDimArray(MethodTable* arrayClass, int8_t* stack, int32_t dimsOffset, int rank)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the actual number of the arguments in the signature, so that the code handles different overloads of array constructor correctly.

Sorry I overlooked this even though you mentioned it. I was focused on #116493 and I think the error was not properly guarding the INTOP_NEWMDARR case, which caused other instance methods to take the same path.

@BrzVlad BrzVlad self-requested a review June 12, 2025 06:48
@BrzVlad BrzVlad dismissed their stale review June 12, 2025 06:49

rank, rank * 2

@kotlarmilos kotlarmilos merged commit e59010b into dotnet:main Jun 13, 2025
96 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Interpreted JIT\CodeGenBringupTests\ArrayMD1/2* tests fail due to num args not matching rank
3 participants