Skip to content
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

Arm64: Implement LoadVector64x* and LoadVector128x* APIs #92855

Merged
merged 19 commits into from
Oct 5, 2023

Conversation

kunalspathak
Copy link
Member

@kunalspathak kunalspathak commented Oct 1, 2023

Add 51 LoadVector* APIs

public static unsafe (Vector128<byte> Value1, Vector128<byte> Value2) LoadVector128x2(byte* address);
public static unsafe (Vector128<sbyte> Value1, Vector128<sbyte> Value2) LoadVector128x2(sbyte* address);
public static unsafe (Vector128<short> Value1, Vector128<short> Value2) LoadVector128x2(short* address);
public static unsafe (Vector128<ushort> Value1, Vector128<ushort> Value2) LoadVector128x2(ushort* address);
public static unsafe (Vector128<int> Value1, Vector128<int> Value2) LoadVector128x2(int* address);
public static unsafe (Vector128<uint> Value1, Vector128<uint> Value2) LoadVector128x2(uint* address);
public static unsafe (Vector128<long> Value1, Vector128<long> Value2) LoadVector128x2(long* address);
public static unsafe (Vector128<ulong> Value1, Vector128<ulong> Value2) LoadVector128x2(ulong* address);
public static unsafe (Vector128<float> Value1, Vector128<float> Value2) LoadVector128x2(float* address);
public static unsafe (Vector128<double> Value1, Vector128<double> Value2) LoadVector128x2(double* address);
public static unsafe (Vector128<byte> Value1, Vector128<byte> Value2, Vector128<byte> Value3) LoadVector128x3(byte* address);
public static unsafe (Vector128<sbyte> Value1, Vector128<sbyte> Value2, Vector128<sbyte> Value3) LoadVector128x3(sbyte* address);
public static unsafe (Vector128<short> Value1, Vector128<short> Value2, Vector128<short> Value3) LoadVector128x3(short* address);
public static unsafe (Vector128<ushort> Value1, Vector128<ushort> Value2, Vector128<ushort> Value3) LoadVector128x3(ushort* address);
public static unsafe (Vector128<int> Value1, Vector128<int> Value2, Vector128<int> Value3) LoadVector128x3(int* address);
public static unsafe (Vector128<uint> Value1, Vector128<uint> Value2, Vector128<uint> Value3) LoadVector128x3(uint* address);
public static unsafe (Vector128<long> Value1, Vector128<long> Value2, Vector128<long> Value3) LoadVector128x3(long* address);
public static unsafe (Vector128<ulong> Value1, Vector128<ulong> Value2, Vector128<ulong> Value3) LoadVector128x3(ulong* address);
public static unsafe (Vector128<float> Value1, Vector128<float> Value2, Vector128<float> Value3) LoadVector128x3(float* address);
public static unsafe (Vector128<double> Value1, Vector128<double> Value2, Vector128<double> Value3) LoadVector128x3(double* address);
public static unsafe (Vector128<byte> Value1, Vector128<byte> Value2, Vector128<byte> Value3, Vector128<byte> Value4) LoadVector128x4(byte* address);
public static unsafe (Vector128<sbyte> Value1, Vector128<sbyte> Value2, Vector128<sbyte> Value3, Vector128<sbyte> Value4) LoadVector128x4(sbyte* address);
public static unsafe (Vector128<short> Value1, Vector128<short> Value2, Vector128<short> Value3, Vector128<short> Value4) LoadVector128x4(short* address);
public static unsafe (Vector128<ushort> Value1, Vector128<ushort> Value2, Vector128<ushort> Value3, Vector128<ushort> Value4) LoadVector128x4(ushort* address);
public static unsafe (Vector128<int> Value1, Vector128<int> Value2, Vector128<int> Value3, Vector128<int> Value4) LoadVector128x4(int* address);
public static unsafe (Vector128<uint> Value1, Vector128<uint> Value2, Vector128<uint> Value3, Vector128<uint> Value4) LoadVector128x4(uint* address);
public static unsafe (Vector128<long> Value1, Vector128<long> Value2, Vector128<long> Value3, Vector128<long> Value4) LoadVector128x4(long* address);
public static unsafe (Vector128<ulong> Value1, Vector128<ulong> Value2, Vector128<ulong> Value3, Vector128<ulong> Value4) LoadVector128x4(ulong* address);        
public static unsafe (Vector128<float> Value1, Vector128<float> Value2, Vector128<float> Value3, Vector128<float> Value4) LoadVector128x4(float* address);
public static unsafe (Vector128<double> Value1, Vector128<double> Value2, Vector128<double> Value3, Vector128<double> Value4) LoadVector128x4(double* address);

public static unsafe (Vector64<byte> Value1, Vector64<byte> Value2) LoadVector64x2(byte* address);
public static unsafe (Vector64<sbyte> Value1, Vector64<sbyte> Value2) LoadVector64x2(sbyte* address);
public static unsafe (Vector64<short> Value1, Vector64<short> Value2) LoadVector64x2(short* address);
public static unsafe (Vector64<ushort> Value1, Vector64<ushort> Value2) LoadVector64x2(ushort* address);
public static unsafe (Vector64<int> Value1, Vector64<int> Value2) LoadVector64x2(int* address);
public static unsafe (Vector64<uint> Value1, Vector64<uint> Value2) LoadVector64x2(uint* address);
public static unsafe (Vector64<float> Value1, Vector64<float> Value2) LoadVector64x2(float* address);
public static unsafe (Vector64<byte> Value1, Vector64<byte> Value2, Vector64<byte> Value3) LoadVector64x3(byte* address);
public static unsafe (Vector64<sbyte> Value1, Vector64<sbyte> Value2, Vector64<sbyte> Value3) LoadVector64x3(sbyte* address);
public static unsafe (Vector64<short> Value1, Vector64<short> Value2, Vector64<short> Value3) LoadVector64x3(short* address);
public static unsafe (Vector64<ushort> Value1, Vector64<ushort> Value2, Vector64<ushort> Value3) LoadVector64x3(ushort* address);
public static unsafe (Vector64<int> Value1, Vector64<int> Value2, Vector64<int> Value3) LoadVector64x3(int* address);
public static unsafe (Vector64<uint> Value1, Vector64<uint> Value2, Vector64<uint> Value3) LoadVector64x3(uint* address);
public static unsafe (Vector64<float> Value1, Vector64<float> Value2, Vector64<float> Value3) LoadVector64x3(float* address);
public static unsafe (Vector64<byte> Value1, Vector64<byte> Value2, Vector64<byte> Value3, Vector64<byte> Value4) LoadVector64x4(byte* address);
public static unsafe (Vector64<sbyte> Value1, Vector64<sbyte> Value2, Vector64<sbyte> Value3, Vector64<sbyte> Value4) LoadVector64x4(sbyte* address);
public static unsafe (Vector64<short> Value1, Vector64<short> Value2, Vector64<short> Value3, Vector64<short> Value4) LoadVector64x4(short* address);
public static unsafe (Vector64<ushort> Value1, Vector64<ushort> Value2, Vector64<ushort> Value3, Vector64<ushort> Value4) LoadVector64x4(ushort* address);
public static unsafe (Vector64<int> Value1, Vector64<int> Value2, Vector64<int> Value3, Vector64<int> Value4) LoadVector64x4(int* address);
public static unsafe (Vector64<uint> Value1, Vector64<uint> Value2, Vector64<uint> Value3, Vector64<uint> Value4) LoadVector64x4(uint* address);
public static unsafe (Vector64<float> Value1, Vector64<float> Value2, Vector64<float> Value3, Vector64<float> Value4) LoadVector64x4(float* address);        

Contributes to #84510

@ghost ghost assigned kunalspathak Oct 1, 2023
@dotnet-issue-labeler dotnet-issue-labeler bot added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI new-api-needs-documentation labels Oct 1, 2023
@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented Oct 1, 2023

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

Issue Details

Add 51 LoadVector* APIs

            public static unsafe (System.Runtime.Intrinsics.Vector128<byte> Value1, System.Runtime.Intrinsics.Vector128<byte> Value2) LoadVector128x2(byte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<sbyte> Value1, System.Runtime.Intrinsics.Vector128<sbyte> Value2) LoadVector128x2(sbyte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<short> Value1, System.Runtime.Intrinsics.Vector128<short> Value2) LoadVector128x2(short* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ushort> Value1, System.Runtime.Intrinsics.Vector128<ushort> Value2) LoadVector128x2(ushort* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<int> Value1, System.Runtime.Intrinsics.Vector128<int> Value2) LoadVector128x2(int* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<uint> Value1, System.Runtime.Intrinsics.Vector128<uint> Value2) LoadVector128x2(uint* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<long> Value1, System.Runtime.Intrinsics.Vector128<long> Value2) LoadVector128x2(long* address)  { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ulong> Value1, System.Runtime.Intrinsics.Vector128<ulong> Value2) LoadVector128x2(ulong* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<float> Value1, System.Runtime.Intrinsics.Vector128<float> Value2) LoadVector128x2(float* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<double> Value1, System.Runtime.Intrinsics.Vector128<double> Value2) LoadVector128x2(double* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<byte> Value1, System.Runtime.Intrinsics.Vector128<byte> Value2, System.Runtime.Intrinsics.Vector128<byte> Value3) LoadVector128x3(byte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<sbyte> Value1, System.Runtime.Intrinsics.Vector128<sbyte> Value2, System.Runtime.Intrinsics.Vector128<sbyte> Value3) LoadVector128x3(sbyte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<short> Value1, System.Runtime.Intrinsics.Vector128<short> Value2, System.Runtime.Intrinsics.Vector128<short> Value3) LoadVector128x3(short* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ushort> Value1, System.Runtime.Intrinsics.Vector128<ushort> Value2, System.Runtime.Intrinsics.Vector128<ushort> Value3) LoadVector128x3(ushort* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<int> Value1, System.Runtime.Intrinsics.Vector128<int> Value2, System.Runtime.Intrinsics.Vector128<int> Value3) LoadVector128x3(int* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<uint> Value1, System.Runtime.Intrinsics.Vector128<uint> Value2, System.Runtime.Intrinsics.Vector128<uint> Value3) LoadVector128x3(uint* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<long> Value1, System.Runtime.Intrinsics.Vector128<long> Value2, System.Runtime.Intrinsics.Vector128<long> Value3) LoadVector128x3(long* address)  { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ulong> Value1, System.Runtime.Intrinsics.Vector128<ulong> Value2, System.Runtime.Intrinsics.Vector128<ulong> Value3) LoadVector128x3(ulong* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<float> Value1, System.Runtime.Intrinsics.Vector128<float> Value2, System.Runtime.Intrinsics.Vector128<float> Value3) LoadVector128x3(float* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<double> Value1, System.Runtime.Intrinsics.Vector128<double> Value2, System.Runtime.Intrinsics.Vector128<double> Value3) LoadVector128x3(double* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<byte> Value1, System.Runtime.Intrinsics.Vector128<byte> Value2, System.Runtime.Intrinsics.Vector128<byte> Value3, System.Runtime.Intrinsics.Vector128<byte> Value4) LoadVector128x4(byte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<sbyte> Value1, System.Runtime.Intrinsics.Vector128<sbyte> Value2, System.Runtime.Intrinsics.Vector128<sbyte> Value3, System.Runtime.Intrinsics.Vector128<sbyte> Value4) LoadVector128x4(sbyte* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<short> Value1, System.Runtime.Intrinsics.Vector128<short> Value2, System.Runtime.Intrinsics.Vector128<short> Value3, System.Runtime.Intrinsics.Vector128<short> Value4) LoadVector128x4(short* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ushort> Value1, System.Runtime.Intrinsics.Vector128<ushort> Value2, System.Runtime.Intrinsics.Vector128<ushort> Value3, System.Runtime.Intrinsics.Vector128<ushort> Value4) LoadVector128x4(ushort* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<int> Value1, System.Runtime.Intrinsics.Vector128<int> Value2, System.Runtime.Intrinsics.Vector128<int> Value3, System.Runtime.Intrinsics.Vector128<int> Value4) LoadVector128x4(int* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<uint> Value1, System.Runtime.Intrinsics.Vector128<uint> Value2, System.Runtime.Intrinsics.Vector128<uint> Value3, System.Runtime.Intrinsics.Vector128<uint> Value4) LoadVector128x4(uint* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<long> Value1, System.Runtime.Intrinsics.Vector128<long> Value2, System.Runtime.Intrinsics.Vector128<long> Value3, System.Runtime.Intrinsics.Vector128<long> Value4) LoadVector128x4(long* address)  { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<ulong> Value1, System.Runtime.Intrinsics.Vector128<ulong> Value2, System.Runtime.Intrinsics.Vector128<ulong> Value3, System.Runtime.Intrinsics.Vector128<ulong> Value4) LoadVector128x4(ulong* address) { throw null; }        
            public static unsafe (System.Runtime.Intrinsics.Vector128<float> Value1, System.Runtime.Intrinsics.Vector128<float> Value2, System.Runtime.Intrinsics.Vector128<float> Value3, System.Runtime.Intrinsics.Vector128<float> Value4) LoadVector128x4(float* address) { throw null; }
            public static unsafe (System.Runtime.Intrinsics.Vector128<double> Value1, System.Runtime.Intrinsics.Vector128<double> Value2, System.Runtime.Intrinsics.Vector128<double> Value3, System.Runtime.Intrinsics.Vector128<double> Value4) LoadVector128x4(double* address) { throw null; }

        public static unsafe (System.Runtime.Intrinsics.Vector64<byte> Value1, System.Runtime.Intrinsics.Vector64<byte> Value2) LoadVector64x2(byte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<sbyte> Value1, System.Runtime.Intrinsics.Vector64<sbyte> Value2) LoadVector64x2(sbyte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<short> Value1, System.Runtime.Intrinsics.Vector64<short> Value2) LoadVector64x2(short* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<ushort> Value1, System.Runtime.Intrinsics.Vector64<ushort> Value2) LoadVector64x2(ushort* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<int> Value1, System.Runtime.Intrinsics.Vector64<int> Value2) LoadVector64x2(int* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<uint> Value1, System.Runtime.Intrinsics.Vector64<uint> Value2) LoadVector64x2(uint* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<float> Value1, System.Runtime.Intrinsics.Vector64<float> Value2) LoadVector64x2(float* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<byte> Value1, System.Runtime.Intrinsics.Vector64<byte> Value2, System.Runtime.Intrinsics.Vector64<byte> Value3) LoadVector64x3(byte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<sbyte> Value1, System.Runtime.Intrinsics.Vector64<sbyte> Value2, System.Runtime.Intrinsics.Vector64<sbyte> Value3) LoadVector64x3(sbyte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<short> Value1, System.Runtime.Intrinsics.Vector64<short> Value2, System.Runtime.Intrinsics.Vector64<short> Value3) LoadVector64x3(short* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<ushort> Value1, System.Runtime.Intrinsics.Vector64<ushort> Value2, System.Runtime.Intrinsics.Vector64<ushort> Value3) LoadVector64x3(ushort* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<int> Value1, System.Runtime.Intrinsics.Vector64<int> Value2, System.Runtime.Intrinsics.Vector64<int> Value3) LoadVector64x3(int* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<uint> Value1, System.Runtime.Intrinsics.Vector64<uint> Value2, System.Runtime.Intrinsics.Vector64<uint> Value3) LoadVector64x3(uint* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<float> Value1, System.Runtime.Intrinsics.Vector64<float> Value2, System.Runtime.Intrinsics.Vector64<float> Value3) LoadVector64x3(float* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<byte> Value1, System.Runtime.Intrinsics.Vector64<byte> Value2, System.Runtime.Intrinsics.Vector64<byte> Value3, System.Runtime.Intrinsics.Vector64<byte> Value4) LoadVector64x4(byte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<sbyte> Value1, System.Runtime.Intrinsics.Vector64<sbyte> Value2, System.Runtime.Intrinsics.Vector64<sbyte> Value3, System.Runtime.Intrinsics.Vector64<sbyte> Value4) LoadVector64x4(sbyte* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<short> Value1, System.Runtime.Intrinsics.Vector64<short> Value2, System.Runtime.Intrinsics.Vector64<short> Value3, System.Runtime.Intrinsics.Vector64<short> Value4) LoadVector64x4(short* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<ushort> Value1, System.Runtime.Intrinsics.Vector64<ushort> Value2, System.Runtime.Intrinsics.Vector64<ushort> Value3, System.Runtime.Intrinsics.Vector64<ushort> Value4) LoadVector64x4(ushort* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<int> Value1, System.Runtime.Intrinsics.Vector64<int> Value2, System.Runtime.Intrinsics.Vector64<int> Value3, System.Runtime.Intrinsics.Vector64<int> Value4) LoadVector64x4(int* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<uint> Value1, System.Runtime.Intrinsics.Vector64<uint> Value2, System.Runtime.Intrinsics.Vector64<uint> Value3, System.Runtime.Intrinsics.Vector64<uint> Value4) LoadVector64x4(uint* address) { throw null; }
        public static unsafe (System.Runtime.Intrinsics.Vector64<float> Value1, System.Runtime.Intrinsics.Vector64<float> Value2, System.Runtime.Intrinsics.Vector64<float> Value3, System.Runtime.Intrinsics.Vector64<float> Value4) LoadVector64x4(float* address) { throw null; }        

Contributes to #84510

Author: kunalspathak
Assignees: kunalspathak
Labels:

area-CodeGen-coreclr, new-api-needs-documentation

Milestone: -

@kunalspathak
Copy link
Member Author

cc: @a74nh @SwapnilGaikwad

src/coreclr/jit/gentree.h Outdated Show resolved Hide resolved
@kunalspathak
Copy link
Member Author

@vargaz - any idea why MinNumberPairwise is failing in mono ?

	  at <unknown> <0xffffffff>
	  at System.Object:__icall_wrapper_mono_gc_alloc_string <0x00007>
	  at System.Object:AllocString <0x00107>
	  at System.String:Concat <0x00103>
	  at TestLibrary.Generator:GetSingle <0x0006f>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.SimpleBinaryOpTest__MinNumberPairwise_Vector64_Single:.ctor <0x002ff>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.Program:MinNumberPairwise_Vector64_Single <0x0003f>
	  at Program:<<Main>$>g__TestExecutor360|0_361 <0x000f3>
	  at Program:<Main>$ <0x01973>
	  at <Module>:runtime_invoke_int_object <0x00087>

@kunalspathak kunalspathak marked this pull request as ready for review October 3, 2023 04:02
@kunalspathak
Copy link
Member Author

@dotnet/jit-contrib @BruceForstall

src/coreclr/jit/lsraarm64.cpp Outdated Show resolved Hide resolved
src/coreclr/jit/lsraarm64.cpp Outdated Show resolved Hide resolved
@kunalspathak
Copy link
Member Author

@vargaz - any idea why MinNumberPairwise is failing in mono ?

	  at <unknown> <0xffffffff>
	  at System.Object:__icall_wrapper_mono_gc_alloc_string <0x00007>
	  at System.Object:AllocString <0x00107>
	  at System.String:Concat <0x00103>
	  at TestLibrary.Generator:GetSingle <0x0006f>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.SimpleBinaryOpTest__MinNumberPairwise_Vector64_Single:.ctor <0x002ff>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.Program:MinNumberPairwise_Vector64_Single <0x0003f>
	  at Program:<<Main>$>g__TestExecutor360|0_361 <0x000f3>
	  at Program:<Main>$ <0x01973>
	  at <Module>:runtime_invoke_int_object <0x00087>

cc: @SamMonoRT @fanyang-mono - Is this the matter of adding an entry in simd-methods.h?

@vargaz
Copy link
Contributor

vargaz commented Oct 4, 2023

@vargaz - any idea why MinNumberPairwise is failing in mono ?

	  at <unknown> <0xffffffff>
	  at System.Object:__icall_wrapper_mono_gc_alloc_string <0x00007>
	  at System.Object:AllocString <0x00107>
	  at System.String:Concat <0x00103>
	  at TestLibrary.Generator:GetSingle <0x0006f>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.SimpleBinaryOpTest__MinNumberPairwise_Vector64_Single:.ctor <0x002ff>
	  at JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64.Program:MinNumberPairwise_Vector64_Single <0x0003f>
	  at Program:<<Main>$>g__TestExecutor360|0_361 <0x000f3>
	  at Program:<Main>$ <0x01973>
	  at <Module>:runtime_invoke_int_object <0x00087>

cc: @SamMonoRT @fanyang-mono - Is this the matter of adding an entry in simd-methods.h?

I can reproduce. The crash appears unrelated to that specific test, the addition of the new LoadVectorX tests triggers it.

@vargaz
Copy link
Contributor

vargaz commented Oct 4, 2023

Also, according to the test output:
Supported ISAs:
AdvSimd: False

The new tests are not even supposed to run.

@kunalspathak
Copy link
Member Author

Also, according to the test output: Supported ISAs: AdvSimd: False

Wondering why AdvSimd: False on linux-arm64 Release leg?

The new tests are not even supposed to run.

That's right, it crashed while trying to run RunUnsupportedScenario().

I can reproduce. The crash appears unrelated to that specific test, the addition of the new LoadVectorX tests triggers it.

I am assuming this PR cannot be merged until we fix this issue. Are you planning to submit a fix in this PR?

@vargaz
Copy link
Contributor

vargaz commented Oct 4, 2023

Also, according to the test output: Supported ISAs: AdvSimd: False

Wondering why AdvSimd: False on linux-arm64 Release leg?

AdvSimd is only supported on mono when running with llvm, not with the mono JIT.

The new tests are not even supposed to run.

That's right, it crashed while trying to run RunUnsupportedScenario().

I can reproduce. The crash appears unrelated to that specific test, the addition of the new LoadVectorX tests triggers it.

I am assuming this PR cannot be merged until we fix this issue. Are you planning to submit a fix in this PR?

Tracking this down will take some time. Would be nice to be able to disable this on mono, but I don't see any such functionality in GenerateHWIntrinsicTests_Arm.cs.

@vargaz
Copy link
Contributor

vargaz commented Oct 4, 2023

The problem seems to be in the DataTable class in the tests:

            public DataTable({Op1BaseType}[] outArray1, {Op1BaseType}[] outArray2, {Op1BaseType}[] inArray, int alignment)
            {
                int sizeOfInArray = inArray.Length * Unsafe.SizeOf<{Op1BaseType}>();
                int sizeOfOutArray1 = outArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
                int sizeOfOutArray2 = outArray2.Length * Unsafe.SizeOf<{Op1BaseType}>();
                if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfInArray || (alignment * 2) < sizeOfOutArray1 || (alignment * 2) < sizeOfOutArray2)
                {
                    throw new ArgumentException("Invalid value of alignment");
                }

                this.inArray = new byte[alignment * 2];
                this.outArray1 = new byte[alignment * 2];
                this.outArray2 = new byte[alignment * 2];

                this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned);
                this.outHandle1 = GCHandle.Alloc(this.outArray1, GCHandleType.Pinned);
                this.outHandle2 = GCHandle.Alloc(this.outArray2, GCHandleType.Pinned);

                this.alignment = (ulong)alignment;

                Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArrayPtr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), (uint)sizeOfInArray);
            }

            public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment);

If inArray is not 16 byte aligned, then the copy done by Unsafe.CopyBlockUnaligned () can write out of the bounds of the array, causing random crashes. This affects all the LoadVectorxTest.template files. A fix would be to bump the
multiplier (i.e. 2 -> 3, 3 -> 4, 4 -> 5) in
this.inArray = new byte[alignment * 2];

@kunalspathak
Copy link
Member Author

A fix would be to bump the multiplier (i.e. 2 -> 3, 3 -> 4, 4 -> 5) in

I am not sure why this is not problem for other test cases.

@kunalspathak
Copy link
Member Author

Copy link
Member Author

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

LGTM. Just a request to update the documentation for LoadVector equivalent.

@kunalspathak
Copy link
Member Author

TM. Just a request to update the documentation for LoadVector equivalent.

Ah, wrong PR :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI new-api-needs-documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants