Compiler::impInitializeArrayIntrinsic in jit/importer.cpp has an early out for multi-dimensional arrays.
// In order to simplify the code, we won't support the multi-dim
// case. Instead we simply return NULL, and the caller will insert
// a run-time call to the helper. Note that we can't assert
// failure here, because this is a valid case.
It would be nice if RyuJIT supported this. It would bring it to parity with the C++ codegen backend
used for .NET Native for UWP apps.
If the @dotnet/jit-contrib team agrees, we might want to tag this as "up-for-grabs". From my uneducated look, this doesn't seem too difficult to implement.
@dotnet/jit-contrib
Sounds like a good idea. "Up for grabs" sounds right without a pressing customer scenario and test case to justify doing this work sooner. Is there a particular test case from .NET native UWP where you noticed this missing with RyuJIT?
I think "up for grabs" sounds good, though it would probably be a non-trivial work item for someone not very familiar with the JIT. That said, I'm not sure there are other, more accessible, work items to designate as "up for grabs".
I noticed it on CoreRT. The .NET Native base class library doesn't have a fallback implementation of InitializeArray and relies on codegen to always expand it. A general purpose fallback implementation for a minimal runtime like CoreRT is relatively costly to implement (both in terms of size on disk hit from generating supporting data structures, and the amount of work to actually do it). We never had the need for it on .NET Native for UWP.
That said, there is a workitem to implement it on CoreRT (dotnet/corert#364), but codegen expansion will always be better.
An up-for-grabs JIT issue? I'll take a look as soon as I have some time :)
I've put together a PR that adds support for multi-dimensional arrays that have all lower bounds = 0. It's not done yet but it seems to work fine with an example I tested:
``` C#
int[,] a = new int[,] { { 1, 2, 3 }, { 4, 3, 4 }, { 4, 5, 6 }, { 1, 2, 3 } };
48B972EE27E0FD7F0000 mov rcx, 0x7FFDE027EE72
BA02000000 mov edx, 2
41B804000000 mov r8d, 4
41B903000000 mov r9d, 3
E8D0F9D05E call CORINFO_HELP_NEW_MDARR
48BA582559A311020000 mov rdx, 0x211A3592558
4883C020 add rax, 32
C4E17A6F02 vmovdqu ymm0, qword ptr [rdx]
C4E17A7F00 vmovdqu qword ptr [rax], ymm0
C4E17A6F4210 vmovdqu ymm0, qword ptr [rdx+16]
C4E17A7F4010 vmovdqu qword ptr [rax+16], ymm0
C4E17A6F4220 vmovdqu ymm0, qword ptr [rdx+32]
C4E17A7F4020 vmovdqu qword ptr [rax+32], ymm0
```
The question is... is it reasonable to compute the pointer to the array data by using a GT_ADD(TYP_REF, TYP_I_IMPL) -> TYP_BYREF node? Using a GenTreeArrElem node would work but it only supports arrays up to rank 3 and generates a lot of code.
@MichalStrehovsky Do you think it's worth supporting arrays with lower bounds != 0? C# doesn't directly support such arrays so the compiler will never generate a call to InitializeArray.
Do you think it's worth supporting arrays with lower bounds != 0? C# doesn't directly support such arrays
C# doesn't, but there could be a different compiler that does support it (VB used to allow that, but now it screams at me when I try anything but 0, so I guess they dropped it).
That said, .NET Native currently doesn't support non-zero lower bounds and since I'm a .NET Native guy, I don't have concerns about not supporting it in the codegen.
OK, I ended up adding support for such arrays anyway. The whole thing is trivial anyway except the IL tests and the pesky x86 call arg ordering. I'll have it ready for review by Monday, assuming that anyone from the JIT team has time for review...
Most helpful comment
I've put together a PR that adds support for multi-dimensional arrays that have all lower bounds = 0. It's not done yet but it seems to work fine with an example I tested:
``` C#
int[,] a = new int[,] { { 1, 2, 3 }, { 4, 3, 4 }, { 4, 5, 6 }, { 1, 2, 3 } };
```
The question is... is it reasonable to compute the pointer to the array data by using a
GT_ADD(TYP_REF, TYP_I_IMPL) -> TYP_BYREFnode? Using aGenTreeArrElemnode would work but it only supports arrays up to rank 3 and generates a lot of code.