runtime: IndexOutOfRangeException in System.Numerics.Vector(array) Where array Size < 32 Bytes
System.Numerics.Vector<byte> vec = new System.Numerics.Vector<byte>(new byte[] { 4, 3, 2, 1, 6, 4, 2, 4 });
This call will crash with an IndexOutOfRangeException exception. I’m pulling in this library as a NuGet package. If I pass in >= 32 bytes, this code works.
The same logic applies to other data types if they do not fill enough at least 32 bytes.
Is there a reason for this behavior? My use case involves passing variable length bytes (anywhere from 1 to millions). The constructor does not make this behavior clear, and I’d prefer to not have to pad my byte arrays to use this.
If the library is not supposed to support values less than the size of the XMM/YMM register, then it would be ideal to at least throw a more specific exception.
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 2
- Comments: 46 (44 by maintainers)
Commits related to this issue
- Fix review comments — committed to dotnet/coreclr by WinCPP 6 years ago
@MarcoRossignoli this is the best we have at the moment: https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md#testing-with-private-coreclr-bits
We want to improve the process, so don’t hesitate to provide feedback. You can add to the docs, create issues, whatever. Please feel free to tag me whenever you do.
https://github.com/dotnet/coreclr/blob/master/src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs has the two line version of the documentation. Comment in front of
Compiler::impIntrinsicin https://github.com/dotnet/coreclr/blob/master/src/jit/importer.cpp has details how these intrinsic methods are recognized and expanded in the JIT.https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/project-guidelines.md#code-file-naming-conventions applied to System.Memory project.
@JeremyKuhne and I talked about this yesterday. @JeremyKuhne Could you please share your plans to make this more straightforward once you have them?
Yes, it is fine to document the current behavior for exception thrown by Vector<T> constructors.
Vector<T>constructors do not follow the framework design guidelines for performance reasons. Another difference from the standard is that they throw NullReferenceException (vs. the ArgumentNullException recommended by the framework design guidelines).COMPlusThrow takes up to 6 extra args eg
in this case the resource is in C:\git\coreclr\src\dlls\mscorrc\mscorrc.rc
@WinCPP I don’t know the best way, but I open this in VS: C:\git\coreclr\bin\obj\Windows_NT.x64.Debug\src\vm\wks\cee_wks.vcxproj
The vcxproj’s are generated by CMake during the build.
@jkotas is there some docs on this?I mean [Intrinsic], *.Portable.cs conventions, debug System.Private.CoreLib etc…i’m very interested to go deeper and help more…but sometimes is a bit cryptic where put the hands(first reason coreclr/corefx are huge code bases with a lot of tecnologies…and this is amazing, the best school). For instance i like to work on System.Private.CoreLib.sln .net side but i haven’t found on guide how to ‘dev/attach debug’ code for that part, i undestood that the tests are all on CoreFx so after write code we need to test with local build. Sorry to all for noise on this issue…but like @WinCPP i did some experiments with same results 😅
Another piece of code to dive into is here:
https://github.com/dotnet/coreclr/blob/aaafa705f6aa930343061a0753928839b1e75bf2/src/jit/simd.cpp#L2647-L2664
What is interesting this are types of checks as above
SCK_RNGCHK_FAILandSCK_ARG_EXCPN@WinCPP JIT uses a
GenTreeBoundsChkIR (withGT_SIMD_CHKoper) to throw the exception.https://github.com/dotnet/coreclr/blob/aaafa705f6aa930343061a0753928839b1e75bf2/src/jit/simd.cpp#L2886-L2906
I guess this change may need to add a new value in
enum SpecialCodeKindbecause the currentSCK_RNGCHK_FAILhas the fixed error message.The implementation of
[Intrinsics]methods is duplicated in the JIT. The code in .cs files is just a fallback for cases where the JIT intrinsic expansion does not kick in (e.g. when the method is called via reflection, or on platforms where the SIMD intrinsics are not implemented yet). It means that the change of exception message has to be done in the JIT to make it actually kick in.Perhaps an exception with more information would be useful then (ie expecting x bytes)
IndexOutOfRangeException is a bit vague for first-time users of this library.
EDIT: Alternatively, address https://github.com/dotnet/corefx/issues/23448 to improve the clarity of what constructor calls do.