From 2055d5610242da81cbc4c767465fddb7dbd78e33 Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Thu, 9 Aug 2018 14:57:39 -0700 Subject: [PATCH] Add test for AVX2 gather intrinsic --- .../X86/Avx2/GatherMaskVector128.cs | 1179 ++++++++++++++++++++ .../X86/Avx2/GatherMaskVector128_r.csproj | 34 + .../X86/Avx2/GatherMaskVector128_ro.csproj | 34 + .../X86/Avx2/GatherMaskVector256.cs | 763 +++++++++++++ .../X86/Avx2/GatherMaskVector256_r.csproj | 34 + .../X86/Avx2/GatherMaskVector256_ro.csproj | 34 + .../HardwareIntrinsics/X86/Avx2/GatherVector128.cs | 1143 +++++++++++++++++++ .../X86/Avx2/GatherVector128_r.csproj | 34 + .../X86/Avx2/GatherVector128_ro.csproj | 34 + .../HardwareIntrinsics/X86/Avx2/GatherVector256.cs | 731 ++++++++++++ .../X86/Avx2/GatherVector256_r.csproj | 34 + .../X86/Avx2/GatherVector256_ro.csproj | 34 + 12 files changed, 4088 insertions(+) create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_r.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_ro.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_r.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_ro.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_r.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_ro.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_r.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_ro.csproj diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs new file mode 100644 index 0000000..b1a8023 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128.cs @@ -0,0 +1,1179 @@ +// 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 = 64; + + 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[4] {8, 16, 32, 63}; + static readonly long[] longIndexTable = new long[2] {16, 32}; + static readonly long[] vector256longIndexTable = new long[4] {8, 16, 32, 63}; + + static readonly int[] intMaskTable = new int[4] {-1, 0, -1, 0}; + static readonly long[] longMaskTable = new long[2] {-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; + } + + Vector128 indexi; + Vector128 indexl; + Vector256 indexl256; + + fixed (int* iptr = intIndexTable) + fixed (long* lptr = longIndexTable) + fixed (long* l256ptr = vector256longIndexTable) + { + indexi = Sse2.LoadVector128(iptr); + indexl = Sse2.LoadVector128(lptr); + indexl256 = Avx.LoadVector256(l256ptr); + } + + Vector128 maski; + Vector128 maskui; + Vector128 maskl; + Vector128 maskul; + Vector128 maskf; + Vector128 maskd; + + fixed (int* iptr = intMaskTable) + fixed (long* lptr = longMaskTable) + { + maski = Sse2.LoadVector128(iptr); + maskl = Sse2.LoadVector128(lptr); + + maskui = Sse.StaticCast(maski); + maskul = Sse.StaticCast(maskl); + maskf = Sse.StaticCast(maski); + maskd = Sse.StaticCast(maskl); + } + + Vector128 sourcei = Sse2.SetZeroVector128(); + Vector128 sourceui = Sse2.SetZeroVector128(); + Vector128 sourcel = Sse2.SetZeroVector128(); + Vector128 sourceul = Sse2.SetZeroVector128(); + Vector128 sourcef = Sse.SetZeroVector128(); + Vector128 sourced = Sse2.SetZeroVector128(); + + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, float* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherMaskVector128(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 GatherMaskVector128 failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(float*), typeof(Vector128), typeof(Vector128), 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 GatherMaskVector128 failed with reflection on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(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 GatherMaskVector128 failed on float with non-const scale (IMM):"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexi, maskf, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, double* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[2])) + { + var vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, 8); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(double*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourced, Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi, maskd, (byte)8 }); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, Eight); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on double with non-const scale (IMM):"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexi, maskd, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, int* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(int*), typeof(Vector128), typeof(Vector128), 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 GatherMaskVector128 failed with reflection on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexi, maski, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, uint* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(uint*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, maskui, (byte)4}); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexi, maskui, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, long* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(long*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourcel, Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi, maskl, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexi, maskl, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, ulong* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(ulong*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourceul, Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi, maskul, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on ulong:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexi, maskul, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, int* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(int*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl, maski, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on int with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl, maski, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, uint* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(uint*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl, maskui, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl, maskui, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, long* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(long*), typeof(Vector128), typeof(Vector128), 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 GatherMaskVector128 failed with reflection on long with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcel, (long*)(longTable.inArrayPtr), indexl, maskl, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, ulong* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(ulong*), typeof(Vector128), typeof(Vector128), 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 GatherMaskVector128 failed with reflection on ulong with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on ulong with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceul, (ulong*)(longTable.inArrayPtr), indexl, maskul, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on long with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, float* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(float*), typeof(Vector128), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl, maskf, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on float with Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl, maskf, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, double* baseAddress, Vector128 index, Vector128 mask, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[2])) + { + var vd = Avx2.GatherMaskVector128(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 GatherMaskVector128 failed on double with Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(double*), typeof(Vector128), typeof(Vector128), 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 GatherMaskVector128 failed with reflection on double with Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherMaskVector128(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 GatherMaskVector128 failed on double with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherMaskVector128(sourced, (double*)(doubletTable.inArrayPtr), indexl, maskd, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on double with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, int* baseAddress, Vector256 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(int*), typeof(Vector256), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourcei, Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl256, maski, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on int with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcei, (int*)(intTable.inArrayPtr), indexl256, maski, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, uint* baseAddress, Vector256 index, Vector128 mask, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(uint*), typeof(Vector256), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourceui, Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl256, maskui, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on uint with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourceui, (uint*)(intTable.inArrayPtr), indexl256, maskui, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherMaskVector128(Vector128 source, float* baseAddress, Vector256 index, Vector128 mask, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherMaskVector128), new Type[] {typeof(Vector128), typeof(float*), typeof(Vector256), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { sourcef, Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl256, maskf, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed with reflection on float with Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, 3); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherMaskVector128 failed on float with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherMaskVector128(sourcef, (float*)(floatTable.inArrayPtr), indexl256, maskf, invalid); + Console.WriteLine("AVX2 GatherMaskVector128 failed on float 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(); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_r.csproj new file mode 100644 index 0000000..fc65c83 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_ro.csproj new file mode 100644 index 0000000..34529b7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector128_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs new file mode 100644 index 0000000..551860c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256.cs @@ -0,0 +1,763 @@ +// 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(); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_r.csproj new file mode 100644 index 0000000..e69bef1 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_ro.csproj new file mode 100644 index 0000000..c20f990 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherMaskVector256_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs new file mode 100644 index 0000000..5142495 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128.cs @@ -0,0 +1,1143 @@ +// 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; + +namespace IntelHardwareIntrinsicTest +{ + class Program + { + const int Pass = 100; + const int Fail = 0; + + const int N = 64; + + 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[4] {8, 16, 32, 63}; + static readonly long[] longIndexTable = new long[2] {16, 32}; + static readonly long[] vector256longIndexTable = new long[4] {8, 16, 32, 63}; + + 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; + } + + Vector128 indexi; + Vector128 indexl; + Vector256 indexl256; + + fixed (int* iptr = intIndexTable) + fixed (long* lptr = longIndexTable) + fixed (long* l256ptr = vector256longIndexTable) + { + indexi = Sse2.LoadVector128(iptr); + indexl = Sse2.LoadVector128(lptr); + indexl256 = Avx.LoadVector256(l256ptr); + } + + // public static unsafe Vector128 GatherVector128(float* baseAddress, Vector128 index, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM):"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on float with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(double* baseAddress, Vector128 index, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[2])) + { + var vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, 8); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(double*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi, (byte)8 }); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on double with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, Eight); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on double with non-const scale (IMM):"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on double with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(int* baseAddress, Vector128 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(uint* baseAddress, Vector128 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(long* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(long*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on long with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on long with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(ulong* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on ulong:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(ulong*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on ulong with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(int* baseAddress, Vector128 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on int with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(uint* baseAddress, Vector128 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint with Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(long* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on long with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(long*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on long with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on long with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on long with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((long*)(longTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(ulong* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[2])) + { + var vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on ulong with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(ulong*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on ulong with Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on ulong with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on ulong with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((ulong*)(longTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on long with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(float* baseAddress, Vector128 index, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float with Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on float with Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on float with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(double* baseAddress, Vector128 index, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[2])) + { + var vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, 8); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on double with Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(double*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, (byte)8 }); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on double with Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector128 failed on double with invalid scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, Eight); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on double with non-const scale (IMM) and Vector128 long index:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector128((double*)(doubletTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on double with invalid non-const scale (IMM) and Vector128 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(int* baseAddress, Vector256 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(int*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexl256, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on int with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, 3); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on int with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((int*)(intTable.inArrayPtr), indexl256, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on int with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(uint* baseAddress, Vector256 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[4])) + { + var vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(uint*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexl256, (byte)4 }); + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on uint with Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, 3); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on uint with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((uint*)(intTable.inArrayPtr), indexl256, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on uint with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector128 GatherVector128(float* baseAddress, Vector256 index, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[4])) + { + var vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float with Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector128)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector128), new Type[] {typeof(float*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexl256, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed with reflection on float with Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, 3); + Console.WriteLine("AVX2 GatherVector128 failed on float with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), vector256longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector128 failed on float with non-const scale (IMM) and Vector256 long index:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector128((float*)(floatTable.inArrayPtr), indexl256, invalid); + Console.WriteLine("AVX2 GatherVector128 failed on float 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++) + { + if (!check(inArray[Convert.ToInt32(indexArray[i])], outArray[i])) + { + return false; + } + } + return true; + } + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_r.csproj new file mode 100644 index 0000000..e58d85d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_ro.csproj new file mode 100644 index 0000000..751b713 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector128_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs new file mode 100644 index 0000000..ab4a5ff --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256.cs @@ -0,0 +1,731 @@ +// 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; + +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 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); + } + + // public static unsafe Vector256 GatherVector256(float* baseAddress, Vector256 index, byte scale) + using (TestTable floatTable = new TestTable(floatSourceTable, new float[8])) + { + var vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, 4); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(float*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(floatTable.inArrayPtr, typeof(float*)), indexi, (byte)4 }); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector256 failed on float with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, Four); + Unsafe.Write(floatTable.outArrayPtr, vf); + + if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == BitConverter.SingleToInt32Bits(y), intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on float with non-const scale (IMM):"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((float*)(floatTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on float with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(double* baseAddress, Vector128 index, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[4])) + { + var vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, 8); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(double*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexi128, (byte)8 }); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on double:"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, 3); + Console.WriteLine("AVX2 GatherVector256 failed on double with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, Eight); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on double with non-const scale (IMM):"); + foreach (var item in doubletTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexi128, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on double with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(int* baseAddress, Vector256 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[8])) + { + var vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(int*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(int*)), indexi, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector256 failed on int with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on int with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((int*)(intTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on int with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(uint* baseAddress, Vector256 index, byte scale) + using (TestTable intTable = new TestTable(intSourceTable, new int[8])) + { + var vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, 4); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(uint*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(intTable.inArrayPtr, typeof(uint*)), indexi, (byte)4 }); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on uint:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, 3); + Console.WriteLine("AVX2 GatherVector256 failed on uint with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, Four); + Unsafe.Write(intTable.outArrayPtr, vf); + + if (!intTable.CheckResult((x, y) => x == y, intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on uint with non-const scale (IMM):"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((uint*)(intTable.inArrayPtr), indexi, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on uint with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(long* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[4])) + { + var vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(long*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexi128, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, 3); + Console.WriteLine("AVX2 GatherVector256 failed on long with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on long with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexi128, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(ulong* baseAddress, Vector128 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[4])) + { + var vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on ulong:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.GatherVector256), new Type[] {typeof(ulong*), typeof(Vector128), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexi128, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed with reflection on ulong:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, 3); + Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, vector128intIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 failed on ulong with non-const scale (IMM):"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + try + { + vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexi128, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid non-const scale (IMM)"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(long* baseAddress, Vector256 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[4])) + { + var vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256), new Type[] {typeof(long*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(long*)), indexl, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((long*)(longTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector256 failed on long with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((long*)(longTable.inArrayPtr), indexl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((long*)(longTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(ulong* baseAddress, Vector256 index, byte scale) + using (TestTable longTable = new TestTable(longSourceTable, new long[4])) + { + var vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, 8); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256), new Type[] {typeof(ulong*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(longTable.inArrayPtr, typeof(ulong*)), indexl, (byte)8 }); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector256 failed on ulong with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vf = Avx2.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, Eight); + Unsafe.Write(longTable.outArrayPtr, vf); + + if (!longTable.CheckResult((x, y) => x == y, longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((ulong*)(longTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector256 failed on long with invalid non-const scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + } + + // public static unsafe Vector256 GatherVector256(double* baseAddress, Vector256 index, byte scale) + using (TestTable doubletTable = new TestTable(doubleSourceTable, new double[4])) + { + var vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, 8); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256), new Type[] {typeof(double*), typeof(Vector256), typeof(byte)}). + Invoke(null, new object[] { Pointer.Box(doubletTable.inArrayPtr, typeof(double*)), indexl, (byte)8 }); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, 3); + Console.WriteLine("AVX2 GatherVector256 failed on double with invalid scale (IMM) and Vector256 long index"); + testResult = Fail; + } + catch (System.ArgumentOutOfRangeException) + { + // sucess + } + + vd = Avx2.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, Eight); + Unsafe.Write(doubletTable.outArrayPtr, vd); + + if (!doubletTable.CheckResult((x, y) => BitConverter.DoubleToInt64Bits(x) == BitConverter.DoubleToInt64Bits(y), longIndexTable)) + { + Console.WriteLine("AVX2 GatherVector256 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.GatherVector256((double*)(doubletTable.inArrayPtr), indexl, invalid); + Console.WriteLine("AVX2 GatherVector256 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++) + { + if (!check(inArray[Convert.ToInt32(indexArray[i])], outArray[i])) + { + return false; + } + } + return true; + } + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_r.csproj new file mode 100644 index 0000000..897b729 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_ro.csproj new file mode 100644 index 0000000..9dd53d5 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/GatherVector256_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + -- 2.7.4