From a71f4bc0f161140855eaf87e27cd82100df0a9e0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 26 Dec 2017 21:01:51 -0800 Subject: [PATCH 1/2] Updating Compiler::impIntrinsic to always expand hardware intrinsics. --- src/jit/importer.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 20007c8cca83..0b6b7de3a54c 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -3378,6 +3378,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool mustExpand = false; bool isSpecial = false; CorInfoIntrinsics intrinsicID = CORINFO_INTRINSIC_Illegal; + NamedIntrinsic ni = NI_Illegal; if ((methodFlags & CORINFO_FLG_INTRINSIC) != 0) { @@ -3388,6 +3389,20 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { // The recursive calls to Jit intrinsics are must-expand by convention. mustExpand = mustExpand || gtIsRecursiveCall(method); + + if (intrinsicID == CORINFO_INTRINSIC_Illegal) + { + ni = lookupNamedIntrinsic(method); + +#if FEATURE_HW_INTRINSICS +#ifdef _TARGET_XARCH_ + if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END) + { + return impX86HWIntrinsic(ni, method, sig); + } +#endif // _TARGET_XARCH_ +#endif // FEATURE_HW_INTRINSICS + } } *pIntrinsicID = intrinsicID; @@ -3875,16 +3890,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, } // Look for new-style jit intrinsics by name - if ((intrinsicID == CORINFO_INTRINSIC_Illegal) && ((methodFlags & CORINFO_FLG_JIT_INTRINSIC) != 0)) + if (ni != NI_Illegal) { assert(retNode == nullptr); - const NamedIntrinsic ni = lookupNamedIntrinsic(method); -#if FEATURE_HW_INTRINSICS && defined(_TARGET_XARCH_) - if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END) - { - return impX86HWIntrinsic(ni, method, sig); - } -#endif // FEATURE_HW_INTRINSICS switch (ni) { case NI_System_Enum_HasFlag: From eaeb4d39ead6004de4734b7dc8bac5b25a29224f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 4 Jan 2018 20:14:03 -0800 Subject: [PATCH 2/2] Updating the existing HWIntrinsic tests to also test indirect calling via reflection. --- .../src/JIT/HardwareIntrinsics/X86/Avx/Add.cs | 36 +++- .../JIT/HardwareIntrinsics/X86/Avx2/Add.cs | 181 +++++++++++++--- .../JIT/HardwareIntrinsics/X86/Lzcnt/Lzcnt.cs | 36 +++- .../HardwareIntrinsics/X86/Popcnt/Popcnt.cs | 36 +++- .../src/JIT/HardwareIntrinsics/X86/Sse/Add.cs | 15 +- .../JIT/HardwareIntrinsics/X86/Sse2/Add.cs | 201 ++++++++++++++---- .../JIT/HardwareIntrinsics/X86/Sse42/Crc32.cs | 54 ++++- 7 files changed, 473 insertions(+), 86 deletions(-) diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.cs index d67adedd9633..47624a086c19 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.cs @@ -30,15 +30,40 @@ static unsafe int Main(string[] args) var vf3 = Avx.Add(vf1, vf2); Unsafe.Write(floatTable.outArrayPtr, vf3); + if (!floatTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX Add failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vf3 = (Vector256)typeof(Avx).GetMethod(nameof(Avx.Add), new Type[] { vf1.GetType(), vf2.GetType() }).Invoke(null, new object[] { vf1, vf2 }); + Unsafe.Write(floatTable.outArrayPtr, vf3); + + if (!floatTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX Add failed via reflection on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + var vd1 = Unsafe.Read>(doubleTable.inArray1Ptr); var vd2 = Unsafe.Read>(doubleTable.inArray2Ptr); var vd3 = Avx.Add(vd1, vd2); Unsafe.Write(doubleTable.outArrayPtr, vd3); - if (!floatTable.CheckResult((x, y, z) => x + y == z)) + if (!doubleTable.CheckResult((x, y, z) => x + y == z)) { - Console.WriteLine("AVX Add failed on float:"); - foreach (var item in floatTable.outArray) + Console.WriteLine("AVX Add failed on double:"); + foreach (var item in doubleTable.outArray) { Console.Write(item + ", "); } @@ -46,9 +71,12 @@ static unsafe int Main(string[] args) testResult = Fail; } + vd3 = (Vector256)typeof(Avx).GetMethod(nameof(Avx.Add), new Type[] { vd1.GetType(), vd2.GetType() }).Invoke(null, new object[] { vd1, vd2 }); + Unsafe.Write(doubleTable.outArrayPtr, vd3); + if (!doubleTable.CheckResult((x, y, z) => x + y == z)) { - Console.WriteLine("AVX Add failed on double:"); + Console.WriteLine("AVX Add failed via reflection on double:"); foreach (var item in doubleTable.outArray) { Console.Write(item + ", "); diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.cs index 6ab142f73d7e..7a84f91d617b 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.cs @@ -37,44 +37,23 @@ static unsafe int Main(string[] args) var vi3 = Avx2.Add(vi1, vi2); Unsafe.Write(intTable.outArrayPtr, vi3); - var vl1 = Unsafe.Read>(longTable.inArray1Ptr); - var vl2 = Unsafe.Read>(longTable.inArray2Ptr); - var vl3 = Avx2.Add(vl1, vl2); - Unsafe.Write(longTable.outArrayPtr, vl3); - - var vui1 = Unsafe.Read>(uintTable.inArray1Ptr); - var vui2 = Unsafe.Read>(uintTable.inArray2Ptr); - var vui3 = Avx2.Add(vui1, vui2); - Unsafe.Write(uintTable.outArrayPtr, vui3); - - var vul1 = Unsafe.Read>(ulongTable.inArray1Ptr); - var vul2 = Unsafe.Read>(ulongTable.inArray2Ptr); - var vul3 = Avx2.Add(vul1, vul2); - Unsafe.Write(ulongTable.outArrayPtr, vul3); - - var vs1 = Unsafe.Read>(shortTable.inArray1Ptr); - var vs2 = Unsafe.Read>(shortTable.inArray2Ptr); - var vs3 = Avx2.Add(vs1, vs2); - Unsafe.Write(shortTable.outArrayPtr, vs3); - - var vus1 = Unsafe.Read>(ushortTable.inArray1Ptr); - var vus2 = Unsafe.Read>(ushortTable.inArray2Ptr); - var vus3 = Avx2.Add(vus1, vus2); - Unsafe.Write(ushortTable.outArrayPtr, vus3); - - var vsb1 = Unsafe.Read>(sbyteTable.inArray1Ptr); - var vsb2 = Unsafe.Read>(sbyteTable.inArray2Ptr); - var vsb3 = Avx2.Add(vsb1, vsb2); - Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + if (!intTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } - var vb1 = Unsafe.Read>(byteTable.inArray1Ptr); - var vb2 = Unsafe.Read>(byteTable.inArray2Ptr); - var vb3 = Avx2.Add(vb1, vb2); - Unsafe.Write(byteTable.outArrayPtr, vb3); + vi3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vi1.GetType(), vi2.GetType() }).Invoke(null, new object[] { vi1, vi2 }); + Unsafe.Write(intTable.outArrayPtr, vi3); if (!intTable.CheckResult((x, y, z) => x + y == z)) { - Console.WriteLine("AVX2 Add failed on int:"); + Console.WriteLine("AVX2 Add failed via reflection on int:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); @@ -83,6 +62,11 @@ static unsafe int Main(string[] args) testResult = Fail; } + var vl1 = Unsafe.Read>(longTable.inArray1Ptr); + var vl2 = Unsafe.Read>(longTable.inArray2Ptr); + var vl3 = Avx2.Add(vl1, vl2); + Unsafe.Write(longTable.outArrayPtr, vl3); + if (!longTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on long:"); @@ -94,6 +78,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vl3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vl1.GetType(), vl2.GetType() }).Invoke(null, new object[] { vl1, vl2 }); + Unsafe.Write(longTable.outArrayPtr, vl3); + + if (!longTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vui1 = Unsafe.Read>(uintTable.inArray1Ptr); + var vui2 = Unsafe.Read>(uintTable.inArray2Ptr); + var vui3 = Avx2.Add(vui1, vui2); + Unsafe.Write(uintTable.outArrayPtr, vui3); + if (!uintTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on uint:"); @@ -105,6 +108,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vui3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vui1.GetType(), vui2.GetType() }).Invoke(null, new object[] { vui1, vui2 }); + Unsafe.Write(uintTable.outArrayPtr, vui3); + + if (!uintTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on uint:"); + foreach (var item in uintTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vul1 = Unsafe.Read>(ulongTable.inArray1Ptr); + var vul2 = Unsafe.Read>(ulongTable.inArray2Ptr); + var vul3 = Avx2.Add(vul1, vul2); + Unsafe.Write(ulongTable.outArrayPtr, vul3); + if (!ulongTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on ulong:"); @@ -116,6 +138,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vul3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vul1.GetType(), vul2.GetType() }).Invoke(null, new object[] { vul1, vul2 }); + Unsafe.Write(ulongTable.outArrayPtr, vul3); + + if (!ulongTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on ulong:"); + foreach (var item in ulongTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vs1 = Unsafe.Read>(shortTable.inArray1Ptr); + var vs2 = Unsafe.Read>(shortTable.inArray2Ptr); + var vs3 = Avx2.Add(vs1, vs2); + Unsafe.Write(shortTable.outArrayPtr, vs3); + if (!shortTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on short:"); @@ -127,6 +168,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vs3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vs1.GetType(), vs2.GetType() }).Invoke(null, new object[] { vs1, vs2 }); + Unsafe.Write(shortTable.outArrayPtr, vs3); + + if (!shortTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on short:"); + foreach (var item in shortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vus1 = Unsafe.Read>(ushortTable.inArray1Ptr); + var vus2 = Unsafe.Read>(ushortTable.inArray2Ptr); + var vus3 = Avx2.Add(vus1, vus2); + Unsafe.Write(ushortTable.outArrayPtr, vus3); + if (!ushortTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on ushort:"); @@ -138,6 +198,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vus3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vus1.GetType(), vus2.GetType() }).Invoke(null, new object[] { vus1, vus2 }); + Unsafe.Write(ushortTable.outArrayPtr, vus3); + + if (!ushortTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on ushort:"); + foreach (var item in ushortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vsb1 = Unsafe.Read>(sbyteTable.inArray1Ptr); + var vsb2 = Unsafe.Read>(sbyteTable.inArray2Ptr); + var vsb3 = Avx2.Add(vsb1, vsb2); + Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + if (!sbyteTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on sbyte:"); @@ -149,6 +228,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vsb3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vsb1.GetType(), vsb2.GetType() }).Invoke(null, new object[] { vsb1, vsb2 }); + Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + + if (!sbyteTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on sbyte:"); + foreach (var item in sbyteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vb1 = Unsafe.Read>(byteTable.inArray1Ptr); + var vb2 = Unsafe.Read>(byteTable.inArray2Ptr); + var vb3 = Avx2.Add(vb1, vb2); + Unsafe.Write(byteTable.outArrayPtr, vb3); + if (!byteTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("AVX2 Add failed on byte:"); @@ -159,8 +257,21 @@ static unsafe int Main(string[] args) Console.WriteLine(); testResult = Fail; } - } + vb3 = (Vector256)typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { vb1.GetType(), vb2.GetType() }).Invoke(null, new object[] { vb1, vb2 }); + Unsafe.Write(byteTable.outArrayPtr, vb3); + + if (!byteTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("AVX2 Add failed via reflection on byte:"); + foreach (var item in byteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } } return testResult; diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Lzcnt/Lzcnt.cs b/tests/src/JIT/HardwareIntrinsics/X86/Lzcnt/Lzcnt.cs index 9d40c08c5429..9489233f2168 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Lzcnt/Lzcnt.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Lzcnt/Lzcnt.cs @@ -4,6 +4,7 @@ // using System; +using System.Reflection; using System.Runtime.Intrinsics.X86; namespace IntelHardwareIntrinsicTest @@ -26,11 +27,22 @@ static int Main(string[] args) Console.WriteLine("Intrinsic Lzcnt.LeadingZeroCount is called on non-supported hardware."); Console.WriteLine("Lzcnt.IsSupported " + Lzcnt.IsSupported); Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); - return Fail; + testResult = Fail; } catch (PlatformNotSupportedException) { - testResult = Pass; + } + + try + { + resl = Convert.ToUInt64(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { sl.GetType() }).Invoke(null, new object[] { sl })); + Console.WriteLine("Intrinsic Lzcnt.LeadingZeroCount is called via reflection on non-supported hardware."); + Console.WriteLine("Lzcnt.IsSupported " + Lzcnt.IsSupported); + Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); + testResult = Fail; + } + catch (TargetInvocationException e) when (e.InnerException is PlatformNotSupportedException) + { } } @@ -42,6 +54,7 @@ static int Main(string[] args) for (int i = 0; i < longLzcntTable.Length; i++) { sl = longLzcntTable[i].s; + resl = Lzcnt.LeadingZeroCount(sl); if (resl != longLzcntTable[i].res) { @@ -49,6 +62,14 @@ static int Main(string[] args) i, sl, longLzcntTable[i].res, resl); testResult = Fail; } + + resl = Convert.ToUInt64(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { sl.GetType() }).Invoke(null, new object[] { sl })); + if (resl != longLzcntTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection", + i, sl, longLzcntTable[i].res, resl); + testResult = Fail; + } } } @@ -56,6 +77,7 @@ static int Main(string[] args) for (int i = 0; i < intLzcntTable.Length; i++) { si = intLzcntTable[i].s; + resi = Lzcnt.LeadingZeroCount(si); if (resi != intLzcntTable[i].res) { @@ -63,6 +85,14 @@ static int Main(string[] args) i, si, intLzcntTable[i].res, resi); testResult = Fail; } + + resl = Convert.ToUInt64(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { si.GetType() }).Invoke(null, new object[] { si })); + if (resi != intLzcntTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection", + i, si, intLzcntTable[i].res, resi); + testResult = Fail; + } } } @@ -96,4 +126,4 @@ public LZCNT(T a, T r) new LZCNT(0x0005423fU, 13) }; } -} \ No newline at end of file +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Popcnt/Popcnt.cs b/tests/src/JIT/HardwareIntrinsics/X86/Popcnt/Popcnt.cs index 20c443ba5366..fd2bdf57d706 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Popcnt/Popcnt.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Popcnt/Popcnt.cs @@ -4,6 +4,7 @@ // using System; +using System.Reflection; using System.Runtime.Intrinsics.X86; namespace IntelHardwareIntrinsicTest @@ -27,11 +28,22 @@ static int Main(string[] args) Console.WriteLine("Intrinsic Popcnt.PopCount is called on non-supported hardware"); Console.WriteLine("Popcnt.IsSupported " + Popcnt.IsSupported); Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); - return Fail; + testResult = Fail; } catch (PlatformNotSupportedException) { - testResult = Pass; + } + + try + { + resl = Convert.ToInt64(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { sl.GetType() }).Invoke(null, new object[] { sl })); + Console.WriteLine("Intrinsic Popcnt.PopCount is called via reflection on non-supported hardware"); + Console.WriteLine("Popcnt.IsSupported " + Popcnt.IsSupported); + Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); + testResult = Fail; + } + catch (TargetInvocationException e) when (e.InnerException is PlatformNotSupportedException) + { } } @@ -43,6 +55,7 @@ static int Main(string[] args) for (int i = 0; i < longPopcntTable.Length; i++) { sl = longPopcntTable[i].s; + resl = Popcnt.PopCount(sl); if (resl != longPopcntTable[i].res) { @@ -50,6 +63,14 @@ static int Main(string[] args) i, sl, longPopcntTable[i].res, resl); testResult = Fail; } + + resl = Convert.ToInt64(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { sl.GetType() }).Invoke(null, new object[] { sl })); + if (resl != longPopcntTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection", + i, sl, longPopcntTable[i].res, resl); + testResult = Fail; + } } } @@ -58,6 +79,7 @@ static int Main(string[] args) for (int i = 0; i < intPopcntTable.Length; i++) { si = intPopcntTable[i].s; + resi = Popcnt.PopCount(si); if (resi != intPopcntTable[i].res) { @@ -65,6 +87,14 @@ static int Main(string[] args) i, si, intPopcntTable[i].res, resi); testResult = Fail; } + + resi = Convert.ToInt32(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { si.GetType() }).Invoke(null, new object[] { si })); + if (resi != intPopcntTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection", + i, si, intPopcntTable[i].res, resi); + testResult = Fail; + } } } @@ -98,4 +128,4 @@ public POPCNT(T a, U r) new POPCNT(0x0005423fU, 10) }; } -} \ No newline at end of file +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.cs index 490bb2a9e690..97f8111e47a8 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.cs @@ -40,10 +40,23 @@ static unsafe int Main(string[] args) Console.WriteLine(); testResult = Fail; } + + vf3 = (Vector128)typeof(Sse).GetMethod(nameof(Sse.Add), new Type[] { vf1.GetType(), vf2.GetType() }).Invoke(null, new object[] { vf1, vf2 }); + Unsafe.Write(floatTable.outArrayPtr, vf3); + + if (!floatTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE Add failed via reflection on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } } } - return testResult; } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.cs index 7c25578fb44e..3d4458c51d32 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.cs @@ -37,49 +37,53 @@ static unsafe int Main(string[] args) var vd3 = Sse2.Add(vd1, vd2); Unsafe.Write(doubleTable.outArrayPtr, vd3); + if (!doubleTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed on double:"); + foreach (var item in doubleTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + vd3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vd1.GetType(), vd2.GetType() }).Invoke(null, new object[] { vd1, vd2 }); + Unsafe.Write(doubleTable.outArrayPtr, vd3); + + if (!doubleTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on double:"); + foreach (var item in doubleTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + var vi1 = Unsafe.Read>(intTable.inArray1Ptr); var vi2 = Unsafe.Read>(intTable.inArray2Ptr); var vi3 = Sse2.Add(vi1, vi2); Unsafe.Write(intTable.outArrayPtr, vi3); - - var vl1 = Unsafe.Read>(longTable.inArray1Ptr); - var vl2 = Unsafe.Read>(longTable.inArray2Ptr); - var vl3 = Sse2.Add(vl1, vl2); - Unsafe.Write(longTable.outArrayPtr, vl3); - - var vui1 = Unsafe.Read>(uintTable.inArray1Ptr); - var vui2 = Unsafe.Read>(uintTable.inArray2Ptr); - var vui3 = Sse2.Add(vui1, vui2); - Unsafe.Write(uintTable.outArrayPtr, vui3); - - var vul1 = Unsafe.Read>(ulongTable.inArray1Ptr); - var vul2 = Unsafe.Read>(ulongTable.inArray2Ptr); - var vul3 = Sse2.Add(vul1, vul2); - Unsafe.Write(ulongTable.outArrayPtr, vul3); - - var vs1 = Unsafe.Read>(shortTable.inArray1Ptr); - var vs2 = Unsafe.Read>(shortTable.inArray2Ptr); - var vs3 = Sse2.Add(vs1, vs2); - Unsafe.Write(shortTable.outArrayPtr, vs3); - - var vus1 = Unsafe.Read>(ushortTable.inArray1Ptr); - var vus2 = Unsafe.Read>(ushortTable.inArray2Ptr); - var vus3 = Sse2.Add(vus1, vus2); - Unsafe.Write(ushortTable.outArrayPtr, vus3); - var vsb1 = Unsafe.Read>(sbyteTable.inArray1Ptr); - var vsb2 = Unsafe.Read>(sbyteTable.inArray2Ptr); - var vsb3 = Sse2.Add(vsb1, vsb2); - Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + if (!intTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } - var vb1 = Unsafe.Read>(byteTable.inArray1Ptr); - var vb2 = Unsafe.Read>(byteTable.inArray2Ptr); - var vb3 = Sse2.Add(vb1, vb2); - Unsafe.Write(byteTable.outArrayPtr, vb3); + vi3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vi1.GetType(), vi2.GetType() }).Invoke(null, new object[] { vi1, vi2 }); + Unsafe.Write(intTable.outArrayPtr, vi3); if (!intTable.CheckResult((x, y, z) => x + y == z)) { - Console.WriteLine("SSE2 Add failed on int:"); + Console.WriteLine("SSE2 Add failed via reflection on int:"); foreach (var item in intTable.outArray) { Console.Write(item + ", "); @@ -88,6 +92,11 @@ static unsafe int Main(string[] args) testResult = Fail; } + var vl1 = Unsafe.Read>(longTable.inArray1Ptr); + var vl2 = Unsafe.Read>(longTable.inArray2Ptr); + var vl3 = Sse2.Add(vl1, vl2); + Unsafe.Write(longTable.outArrayPtr, vl3); + if (!longTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on long:"); @@ -99,6 +108,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vl3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vl1.GetType(), vl2.GetType() }).Invoke(null, new object[] { vl1, vl2 }); + Unsafe.Write(longTable.outArrayPtr, vl3); + + if (!longTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vui1 = Unsafe.Read>(uintTable.inArray1Ptr); + var vui2 = Unsafe.Read>(uintTable.inArray2Ptr); + var vui3 = Sse2.Add(vui1, vui2); + Unsafe.Write(uintTable.outArrayPtr, vui3); + if (!uintTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on uint:"); @@ -110,6 +138,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vui3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vui1.GetType(), vui2.GetType() }).Invoke(null, new object[] { vui1, vui2 }); + Unsafe.Write(uintTable.outArrayPtr, vui3); + + if (!uintTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on uint:"); + foreach (var item in uintTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vul1 = Unsafe.Read>(ulongTable.inArray1Ptr); + var vul2 = Unsafe.Read>(ulongTable.inArray2Ptr); + var vul3 = Sse2.Add(vul1, vul2); + Unsafe.Write(ulongTable.outArrayPtr, vul3); + if (!ulongTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on ulong:"); @@ -121,6 +168,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vul3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vul1.GetType(), vul2.GetType() }).Invoke(null, new object[] { vul1, vul2 }); + Unsafe.Write(ulongTable.outArrayPtr, vul3); + + if (!ulongTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on ulong:"); + foreach (var item in ulongTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vs1 = Unsafe.Read>(shortTable.inArray1Ptr); + var vs2 = Unsafe.Read>(shortTable.inArray2Ptr); + var vs3 = Sse2.Add(vs1, vs2); + Unsafe.Write(shortTable.outArrayPtr, vs3); + if (!shortTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on short:"); @@ -132,6 +198,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vs3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vs1.GetType(), vs2.GetType() }).Invoke(null, new object[] { vs1, vs2 }); + Unsafe.Write(shortTable.outArrayPtr, vs3); + + if (!shortTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on short:"); + foreach (var item in shortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vus1 = Unsafe.Read>(ushortTable.inArray1Ptr); + var vus2 = Unsafe.Read>(ushortTable.inArray2Ptr); + var vus3 = Sse2.Add(vus1, vus2); + Unsafe.Write(ushortTable.outArrayPtr, vus3); + if (!ushortTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on ushort:"); @@ -143,10 +228,13 @@ static unsafe int Main(string[] args) testResult = Fail; } - if (!doubleTable.CheckResult((x, y, z) => x + y == z)) + vus3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vus1.GetType(), vus2.GetType() }).Invoke(null, new object[] { vus1, vus2 }); + Unsafe.Write(ushortTable.outArrayPtr, vus3); + + if (!ushortTable.CheckResult((x, y, z) => x + y == z)) { - Console.WriteLine("SSE2 Add failed on double:"); - foreach (var item in doubleTable.outArray) + Console.WriteLine("SSE2 Add failed via reflection on ushort:"); + foreach (var item in ushortTable.outArray) { Console.Write(item + ", "); } @@ -154,6 +242,11 @@ static unsafe int Main(string[] args) testResult = Fail; } + var vsb1 = Unsafe.Read>(sbyteTable.inArray1Ptr); + var vsb2 = Unsafe.Read>(sbyteTable.inArray2Ptr); + var vsb3 = Sse2.Add(vsb1, vsb2); + Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + if (!sbyteTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on sbyte:"); @@ -165,6 +258,25 @@ static unsafe int Main(string[] args) testResult = Fail; } + vsb3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vsb1.GetType(), vsb2.GetType() }).Invoke(null, new object[] { vsb1, vsb2 }); + Unsafe.Write(sbyteTable.outArrayPtr, vsb3); + + if (!sbyteTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on sbyte:"); + foreach (var item in sbyteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + + var vb1 = Unsafe.Read>(byteTable.inArray1Ptr); + var vb2 = Unsafe.Read>(byteTable.inArray2Ptr); + var vb3 = Sse2.Add(vb1, vb2); + Unsafe.Write(byteTable.outArrayPtr, vb3); + if (!byteTable.CheckResult((x, y, z) => x + y == z)) { Console.WriteLine("SSE2 Add failed on byte:"); @@ -175,6 +287,21 @@ static unsafe int Main(string[] args) Console.WriteLine(); testResult = Fail; } + + vb3 = (Vector128)typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { vb1.GetType(), vb2.GetType() }).Invoke(null, new object[] { vb1, vb2 }); + Unsafe.Write(byteTable.outArrayPtr, vb3); + + if (!byteTable.CheckResult((x, y, z) => x + y == z)) + { + Console.WriteLine("SSE2 Add failed via reflection on byte:"); + foreach (var item in byteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Crc32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Crc32.cs index 27ea5a9bbf80..043bcbb2d0cd 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Crc32.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Crc32.cs @@ -4,6 +4,7 @@ // using System; +using System.Reflection; using System.Runtime.Intrinsics.X86; namespace IntelHardwareIntrinsicTest @@ -26,11 +27,22 @@ static int Main(string[] args) Console.WriteLine("Intrinsic Sse42.Crc32 is called on non-supported hardware."); Console.WriteLine("Sse42.IsSupported " + Sse42.IsSupported); Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); - return Fail; + testResult = Fail; } catch (PlatformNotSupportedException) { - testResult = Pass; + } + + try + { + resl = Convert.ToUInt64(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { s1l.GetType(), s2l.GetType() }).Invoke(null, new object[] { s1l, s2l })); + Console.WriteLine("Intrinsic Sse42.Crc32 is called via reflection on non-supported hardware."); + Console.WriteLine("Sse42.IsSupported " + Sse42.IsSupported); + Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess); + testResult = Fail; + } + catch (TargetInvocationException e) when (e.InnerException is PlatformNotSupportedException) + { } } @@ -43,6 +55,7 @@ static int Main(string[] args) { s1l = longCrcTable[i].s1; s2l = longCrcTable[i].s2; + resl = Sse42.Crc32(s1l, s2l); if (resl != longCrcTable[i].res) { @@ -50,6 +63,14 @@ static int Main(string[] args) i, s1l, s2l, longCrcTable[i].res, resl); testResult = Fail; } + + resl = Convert.ToUInt64(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { s1l.GetType(), s2l.GetType() }).Invoke(null, new object[] { s1l, s2l })); + if (resl != longCrcTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,16:x}, 0x{2,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection", + i, s1l, s2l, longCrcTable[i].res, resl); + testResult = Fail; + } } } @@ -58,6 +79,7 @@ static int Main(string[] args) { s1i = intCrcTable[i].s1; s2i = intCrcTable[i].s2; + resi = Sse42.Crc32(s1i, s2i); if (resi != intCrcTable[i].res) { @@ -65,6 +87,14 @@ static int Main(string[] args) i, s1i, s2i, intCrcTable[i].res, resi); testResult = Fail; } + + resi = Convert.ToUInt32(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { s1i.GetType(), s2i.GetType() }).Invoke(null, new object[] { s1i, s2i })); + if (resi != intCrcTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,8:x}, 0x{2,8:x} Expected: 0x{3,8:x} actual: 0x{4,8:x} - Reflection", + i, s1i, s2i, intCrcTable[i].res, resi); + testResult = Fail; + } } ushort s2s; @@ -72,6 +102,7 @@ static int Main(string[] args) { s1i = shortCrcTable[i].s1; s2s = shortCrcTable[i].s2; + resi = Sse42.Crc32(s1i, s2s); if (resi != shortCrcTable[i].res) { @@ -79,6 +110,14 @@ static int Main(string[] args) i, s1i, s2s, shortCrcTable[i].res, resi); testResult = Fail; } + + resi = Convert.ToUInt32(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { s1i.GetType(), s2s.GetType() }).Invoke(null, new object[] { s1i, s2s })); + if (resi != shortCrcTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,8:x}, 0x{2,8:x} Expected: 0x{3,8:x} actual: 0x{4,8:x} - Reflection", + i, s1i, s2s, shortCrcTable[i].res, resi); + testResult = Fail; + } } byte s2b; @@ -86,6 +125,7 @@ static int Main(string[] args) { s1i = byteCrcTable[i].s1; s2b = byteCrcTable[i].s2; + resi = Sse42.Crc32(s1i, s2b); if (resi != byteCrcTable[i].res) { @@ -93,6 +133,14 @@ static int Main(string[] args) i, s1i, s2b, byteCrcTable[i].res, resi); testResult = Fail; } + + resi = Convert.ToUInt32(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { s1i.GetType(), s2b.GetType() }).Invoke(null, new object[] { s1i, s2b })); + if (resi != byteCrcTable[i].res) + { + Console.WriteLine("{0}: Inputs: 0x{1,8:x}, 0x{2,8:x} Expected: 0x{3,8:x} actual: 0x{4,8:x}", + i, s1i, s2b, byteCrcTable[i].res, resi); + testResult = Fail; + } } } @@ -177,4 +225,4 @@ public Crc(T a, U b, T c) }; } -} \ No newline at end of file +}