// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // using System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics; using System.Collections.Generic; namespace IntelHardwareIntrinsicTest { class Program { const int Pass = 100; const int Fail = 0; const int N = 128; static byte Four; static byte Eight; static byte invalid; static readonly float[] floatSourceTable = new float[N]; static readonly double[] doubleSourceTable = new double[N]; static readonly int[] intSourceTable = new int[N]; static readonly long[] longSourceTable = new long[N]; static readonly int[] intIndexTable = new int[8] {1, 2, 4, 8, 16, 32, 40, 63}; static readonly long[] longIndexTable = new long[4] {2, 8, 16, 32}; static readonly int[] vector128intIndexTable = new int[4] {8, 16, 32, 63}; static readonly int[] intMaskTable = new int[8] {-1, 0, -1, 0, -1, 0, -1, 0}; static readonly long[] longMaskTable = new long[4] {-1, 0, -1, 0}; static unsafe int Main(string[] args) { int testResult = Pass; if (Avx2.IsSupported) { Four = 4; Eight = 8; invalid = 15; for (int i = 0; i < N; i++) { floatSourceTable[i] = (float)i * 10.0f; doubleSourceTable[i] = (double)i * 10.0; intSourceTable[i] = i * 10; longSourceTable[i] = i * 10; } Vector256 indexi; Vector256 indexl; Vector128 indexi128; fixed (int* iptr = intIndexTable) fixed (long* lptr = longIndexTable) fixed (int* i128ptr = vector128intIndexTable) { indexi = Avx.LoadVector256(iptr); indexl = Avx.LoadVector256(lptr); indexi128 = Sse2.LoadVector128(i128ptr); } Vector256 maski; Vector256 maskui; Vector256 maskl; Vector256 maskul; Vector256 maskf; Vector256 maskd; fixed (int* iptr = intMaskTable) fixed (long* lptr = longMaskTable) { maski = Avx.LoadVector256(iptr); maskl = Avx.LoadVector256(lptr); maskui = Avx.StaticCast(maski); maskul = Avx.StaticCast(maskl); maskf = Avx.StaticCast(maski); maskd = Avx.StaticCast(maskl); } Vector256 sourcei = Avx.SetZeroVector256(); Vector256 sourceui = Avx.SetZeroVector256(); Vector256 sourcel = Avx.SetZeroVector256(); Vector256 sourceul = Avx.SetZeroVector256(); Vector256 sourcef = Avx.SetZeroVector256(); Vector256 sourced = Avx.SetZeroVector256(); // public static unsafe Vector256 GatherMaskVector256(Vector256 source, float* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable floatTable = new TestTable(floatSourceTable, new float[8])) { var vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 4); Unsafe.Write(floatTable.outArrayPtr, vf); if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on float:"); foreach (var item in floatTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(float*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, maskf, (byte)4 }); Unsafe.Write(floatTable.outArrayPtr, vf); if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on float:"); foreach (var item in floatTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on float with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, Four); Unsafe.Write(floatTable.outArrayPtr, vf); if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on float with non-const scale (IMM):"); foreach (var item in floatTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on float with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, double* baseAddress, Vector128 index, Vector256 mask, byte scale) using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[4])) { var vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd, 8); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on double:"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vd = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(double*), typeof(Vector128), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi128, maskd, (byte)8 }); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on double:"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd, Eight); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on double with non-const scale (IMM):"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexi128, maskd, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, int* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable intTable = new TestTable(intSourceTable, new int[8])) { var vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 4); Unsafe.Write(intTable.outArrayPtr, vf); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on int:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(int*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, maski, (byte)4 }); Unsafe.Write(intTable.outArrayPtr, vf); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on int:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on int with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, Four); Unsafe.Write(intTable.outArrayPtr, vf); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on int with non-const scale (IMM):"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on int with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, uint* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable intTable = new TestTable(intSourceTable, new int[8])) { var vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 4); Unsafe.Write(intTable.outArrayPtr, vf); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on uint:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(uint*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, maskui, (byte)4 }); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on uint:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, Four); Unsafe.Write(intTable.outArrayPtr, vf); if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with non-const scale (IMM):"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on uint with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, long* baseAddress, Vector128 index, Vector256 mask, byte scale) using (TestTable longTable = new TestTable(longSourceTable, new long[4])) { var vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, 8); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on long:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(long*), typeof(Vector128), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi128, maskl, (byte)8 }); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on long:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, Eight); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on long with non-const scale (IMM):"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexi128, maskl, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, ulong* baseAddress, Vector128 index, Vector256 mask, byte scale) using (TestTable longTable = new TestTable(longSourceTable, new long[4])) { var vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul, 8); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(ulong*), typeof(Vector128), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi128, maskul, (byte)8 }); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on ulong:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul, Eight); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with non-const scale (IMM):"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexi128, maskul, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid non-const scale (IMM)"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, long* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable longTable = new TestTable(longSourceTable, new long[4])) { var vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 8); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on long with Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(long*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, maskl, (byte)8 }); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on long with Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, Eight); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on long with non-const scale (IMM) and Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, ulong* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable longTable = new TestTable(longSourceTable, new long[4])) { var vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 8); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(ulong*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, maskul, (byte)8 }); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on ulong with Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with invalid scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, Eight); Unsafe.Write(longTable.outArrayPtr, vf); if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on ulong with non-const scale (IMM) and Vector256 long index:"); foreach (var item in longTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vf = Avx2.GatherMaskVector256(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } // public static unsafe Vector256 GatherMaskVector256(Vector256 source, double* baseAddress, Vector256 index, Vector256 mask, byte scale) using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[4])) { var vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 8); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on double with Vector256 long index:"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } vd = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector256), new Type[] {typeof(Vector256), typeof(double*), typeof(Vector256), typeof(Vector256), typeof(byte)}). Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, maskd, (byte)8 }); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed with reflection on double with Vector256 long index:"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 3); Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, Eight); Unsafe.Write(doubletTable.outArrayPtr, vd); if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) { Console.WriteLine("AVX2 GatherMaskVector256 failed on double with non-const scale (IMM) and Vector256 long index:"); foreach (var item in doubletTable.outArray) { Console.Write(item + ", "); } Console.WriteLine(); testResult = Fail; } try { vd = Avx2.GatherMaskVector256(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, invalid); Console.WriteLine("AVX2 GatherMaskVector256 failed on double with invalid non-const scale (IMM) and Vector256 long index"); testResult = Fail; } catch (System.ArgumentOutOfRangeException) { // sucess } } } return testResult; } public unsafe struct TestTable : IDisposable where T : struct where U : struct { public T[] inArray; public T[] outArray; public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer(); public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); GCHandle inHandle; GCHandle outHandle; public TestTable(T[] a, T[] b) { this.inArray = a; this.outArray = b; inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned); outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); } public bool CheckResult(Func check, U[] indexArray) { int length = Math.Min(indexArray.Length, outArray.Length); for (int i = 0; i < length; i++) { bool take = i % 2 == 0; if ((take && !check(inArray[Convert.ToInt32(indexArray[i])], outArray[i])) || (!take && !EqualityComparer.Default.Equals(outArray[i], default(T)))) { return false; } } return true; } public void Dispose() { inHandle.Free(); outHandle.Free(); } } } }