diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp index 18240a4f5ec2..b0029a3a99e6 100644 --- a/src/jit/lsraxarch.cpp +++ b/src/jit/lsraxarch.cpp @@ -2528,7 +2528,7 @@ void LinearScan::TreeNodeInfoInitHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, case NI_SSE_CompareNotEqualOrderedScalar: case NI_SSE_CompareNotEqualUnorderedScalar: info->internalIntCount = 1; - info->setInternalCandidates(this, allRegs(TYP_INT)); + info->setInternalCandidates(this, RBM_BYTE_REGS); break; case NI_SSE_SetScalar: diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template new file mode 100644 index 000000000000..a8ea21cef8bb --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{{ + public static partial class Program + {{ + private static void {1}{2}() + {{ + var test = new BooleanComparisonOpTest__{1}{2}(); + + if (test.IsSupported) + {{ + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + }} + else + {{ + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + }} + + if (!test.Succeeded) + {{ + throw new Exception("One or more scenarios did not complete as expected."); + }} + }} + }} + + public sealed unsafe class BooleanComparisonOpTest__{1}{2} + {{ + private const int VectorSize = {4}; + private const int ElementCount = VectorSize / sizeof({2}); + + private static {2}[] _data1 = new {2}[ElementCount]; + private static {2}[] _data2 = new {2}[ElementCount]; + + private static {3}<{2}> _clsVar1; + private static {3}<{2}> _clsVar2; + + private {3}<{2}> _fld1; + private {3}<{2}> _fld2; + + private BooleanComparisonOpTest__DataTable<{2}> _dataTable; + + static BooleanComparisonOpTest__{1}{2}() + {{ + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) {{ _data1[i] = {5}; _data2[i] = {5}; }} + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{3}<{2}>, byte>(ref _clsVar1), ref Unsafe.As<{2}, byte>(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{3}<{2}>, byte>(ref _clsVar2), ref Unsafe.As<{2}, byte>(ref _data1[0]), VectorSize); + }} + + public BooleanComparisonOpTest__{1}{2}() + {{ + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) {{ _data1[i] = {5}; _data2[i] = {5}; }} + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{3}<{2}>, byte>(ref _fld1), ref Unsafe.As<{2}, byte>(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{3}<{2}>, byte>(ref _fld2), ref Unsafe.As<{2}, byte>(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) {{ _data1[i] = {5}; _data2[i] = {5}; }} + _dataTable = new BooleanComparisonOpTest__DataTable<{2}>(_data1, _data2); + }} + + public bool IsSupported => {0}.IsSupported; + + public bool Succeeded {{ get; set; }} + + public void RunBasicScenario() + {{ + var result = {0}.{1}( + Unsafe.Read<{3}<{2}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{3}<{2}>>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + }} + + public void RunReflectionScenario() + {{ + var result = typeof({0}).GetMethod(nameof({0}.{1}), new Type[] {{ typeof({3}<{2}>), typeof({3}<{2}>) }}) + .Invoke(null, new object[] {{ + Unsafe.Read<{3}<{2}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{3}<{2}>>(_dataTable.inArray2Ptr) + }}); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + }} + + public void RunClsVarScenario() + {{ + var result = {0}.{1}( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + }} + + public void RunLclVarScenario() + {{ + var left = Unsafe.Read<{3}<{2}>>(_dataTable.inArray1Ptr); + var right = Unsafe.Read<{3}<{2}>>(_dataTable.inArray2Ptr); + var result = {0}.{1}(left, right); + + ValidateResult(left, right, result); + }} + + public void RunLclFldScenario() + {{ + var test = new BooleanComparisonOpTest__{1}{2}(); + var result = {0}.{1}(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + }} + + public void RunFldScenario() + {{ + var result = {0}.{1}(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + }} + + public void RunUnsupportedScenario() + {{ + Succeeded = false; + + try + {{ + RunBasicScenario(); + }} + catch (PlatformNotSupportedException) + {{ + Succeeded = true; + }} + }} + + private void ValidateResult({3}<{2}> left, {3}<{2}> right, bool result, [CallerMemberName] string method = "") + {{ + {2}[] inArray1 = new {2}[ElementCount]; + {2}[] inArray2 = new {2}[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + }} + + private void ValidateResult({2}[] left, {2}[] right, bool result, [CallerMemberName] string method = "") + {{ + if ({6}) + {{ + Succeeded = false; + + Console.WriteLine($"{{nameof({0})}}.{{nameof({0}.{1})}}<{2}>: {{method}} failed:"); + Console.WriteLine($" left: ({{string.Join(", ", left)}})"); + Console.WriteLine($" right: ({{string.Join(", ", right)}})"); + Console.WriteLine($" result: ({{string.Join(", ", result)}})"); + Console.WriteLine(); + }} + }} + }} +}} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs new file mode 100644 index 000000000000..56f07fb685fe --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs @@ -0,0 +1,39 @@ +// 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.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public unsafe struct BooleanComparisonOpTest__DataTable : IDisposable where T : struct + { + private GCHandle inHandle1; + private GCHandle inHandle2; + + public T[] inArray1; + public T[] inArray2; + + public BooleanComparisonOpTest__DataTable(T[] inArray1, T[] inArray2) + { + this.inArray1 = inArray1; + this.inArray2 = inArray2; + + this.inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); + } + + public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); + public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx index 7dbc5af4f5d9..c5850cb1d484 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx @@ -19,20 +19,60 @@ using System.IO; // "ProcessInputs" call at the bottom of the script. private static readonly (string templateFileName, string[] templateData)[] SseInputs = new [] -{ - // TemplateName Isa, Method, BaseType, VectorType, VectorSize, NextValue, ValidateFirstResult, ValidateRemainingResults - ("SimpleBinOpTest.template", new string[] { "Sse", "Add", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "AddScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "And", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "AndNot", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(~BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(~BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "Divide", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] / right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] / right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "DivideScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] / right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "Multiply", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] * right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "MultiplyScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "Or", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) | BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) | BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "Subtract", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] - right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "SubtractScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new string[] { "Sse", "Xor", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) ^ BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) ^ BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), +{ + // TemplateName Isa, Method, BaseType, VectorType, VectorSize, NextValue, ValidateFirstResult, ValidateRemainingResults + ("SimpleBinOpTest.template", new string[] { "Sse", "Add", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "AddScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "And", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "AndNot", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(~BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(~BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareEqualOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] == right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareEqualUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] == right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareGreaterThan", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareGreaterThanScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareGreaterThanOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] > right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareGreaterThanUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] > right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareGreaterThanOrEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareGreaterThanOrEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareGreaterThanOrEqualOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] >= right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareGreaterThanOrEqualUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] >= right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareLessThan", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareLessThanScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareLessThanOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] < right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareLessThanUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] < right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareLessThanOrEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareLessThanOrEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareLessThanOrEqualOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] <= right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareLessThanOrEqualUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] <= right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareNotEqualOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] != right[0]) != result"}), + ("BooleanCmpOpTest.template", new string[] { "Sse", "CompareNotEqualUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(left[0] != right[0]) != result"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotGreaterThan", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotGreaterThanScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotGreaterThanOrEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotGreaterThanOrEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotLessThan", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotLessThanScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotLessThanOrEqual", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareNotLessThanOrEqualScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareOrdered", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((!float.IsNaN(left[0]) && !float.IsNaN(right[0])) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((!float.IsNaN(left[i]) && !float.IsNaN(right[i])) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareOrderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((!float.IsNaN(left[0]) && !float.IsNaN(right[0])) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareUnordered", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((float.IsNaN(left[0]) || float.IsNaN(right[0])) ? -1 : 0)", "BitConverter.SingleToInt32Bits(result[i]) != ((float.IsNaN(left[i]) || float.IsNaN(right[i])) ? -1 : 0)"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "CompareUnorderedScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(result[0]) != ((float.IsNaN(left[0]) || float.IsNaN(right[0])) ? -1 : 0)", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Divide", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] / right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] / right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "DivideScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] / right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Max", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(Math.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(Math.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "MaxScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(Math.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Min", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(Math.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(Math.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "MinScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(Math.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Multiply", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] * right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "MultiplyScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Or", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) | BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) | BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Subtract", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] - right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "SubtractScalar", "Single", "Vector128", "16", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new string[] { "Sse", "Xor", "Single", "Vector128", "16", "(float)(random.NextDouble())", "(BitConverter.SingleToInt32Bits(left[0]) ^ BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", "(BitConverter.SingleToInt32Bits(left[0]) ^ BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])"}), }; private static readonly (string templateFileName, string[] templateData)[] Sse2Inputs = new [] diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs new file mode 100644 index 000000000000..a5b793457027 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareEqualSingle(); + var result = Sse.CompareEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.cs deleted file mode 100644 index 46a7789668b1..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x == y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.Single.cs new file mode 100644 index 000000000000..19e2e024d3e7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareEqualOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareEqualOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareEqualOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareEqualOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareEqualOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareEqualOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareEqualOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareEqualOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareEqualOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareEqualOrderedScalarSingle(); + var result = Sse.CompareEqualOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareEqualOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] == right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareEqualOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.cs deleted file mode 100644 index 5fd6a5883892..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareEqualOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareEqualOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar_r.csproj deleted file mode 100644 index 2bec7814d867..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar_ro.csproj deleted file mode 100644 index 5cdcb8efdfef..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar.Single.cs new file mode 100644 index 000000000000..3a963b32673e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareEqualScalarSingle(); + var result = Sse.CompareEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar.cs deleted file mode 100644 index 402751a0c795..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] == y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar_r.csproj deleted file mode 100644 index 6f0e8a675a63..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar_ro.csproj deleted file mode 100644 index 6d6350b2515a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqualUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar.Single.cs new file mode 100644 index 000000000000..4e95e71eb59c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareEqualUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareEqualUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareEqualUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareEqualUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareEqualUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareEqualUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareEqualUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareEqualUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareEqualUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareEqualUnorderedScalarSingle(); + var result = Sse.CompareEqualUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareEqualUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] == right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareEqualUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar.cs deleted file mode 100644 index eb68c6c798b9..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareEqualUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareEqualUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar_r.csproj deleted file mode 100644 index ddc86dbd432a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar_ro.csproj deleted file mode 100644 index aac8f24e7351..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqualUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual_r.csproj deleted file mode 100644 index 0261014260a1..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual_ro.csproj deleted file mode 100644 index aebb467439b8..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs new file mode 100644 index 000000000000..54bc76d030bc --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanSingle() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareGreaterThanSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareGreaterThanSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThan( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThan), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThan( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThan(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanSingle(); + var result = Sse.CompareGreaterThan(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThan(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThan)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.cs deleted file mode 100644 index d2ce38cd38ff..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareGreaterThan(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x > y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareGreaterThan failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs new file mode 100644 index 000000000000..efe221858a8e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanOrEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanOrEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanOrEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanOrEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle(); + var result = Sse.CompareGreaterThanOrEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanOrEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanOrEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.cs deleted file mode 100644 index daa4a2a57242..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareGreaterThanOrEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x >= y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareGreaterThanOrEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.Single.cs new file mode 100644 index 000000000000..9c8b6e4d30dd --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanOrEqualOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanOrEqualOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqualOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanOrEqualOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanOrEqualOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualOrderedScalarSingle(); + var result = Sse.CompareGreaterThanOrEqualOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanOrEqualOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] >= right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanOrEqualOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.cs deleted file mode 100644 index a3b85fcd272c..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareGreaterThanOrEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrEqualOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareGreaterThanOrEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrEqualOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar_r.csproj deleted file mode 100644 index e1394762550f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar_ro.csproj deleted file mode 100644 index 082bb91202b9..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar.Single.cs new file mode 100644 index 000000000000..638bd2e7ce37 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanOrEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanOrEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanOrEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanOrEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualScalarSingle(); + var result = Sse.CompareGreaterThanOrEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanOrEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanOrEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar.cs deleted file mode 100644 index ea20d1cdcc94..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareGreaterThanOrEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] >= y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareGreaterThanOrEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar_r.csproj deleted file mode 100644 index 83c37e207b2c..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar_ro.csproj deleted file mode 100644 index 2144c9eba006..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqualUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar.Single.cs new file mode 100644 index 000000000000..c1c4a7f707f3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanOrEqualUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanOrEqualUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanOrEqualUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanOrEqualUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrEqualUnorderedScalarSingle(); + var result = Sse.CompareGreaterThanOrEqualUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanOrEqualUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] >= right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanOrEqualUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar.cs deleted file mode 100644 index b7a6e9027630..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareGreaterThanOrEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrEqualUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareGreaterThanOrEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrEqualUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar_r.csproj deleted file mode 100644 index b6bf9d86ae51..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj deleted file mode 100644 index 5516f55368d1..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqualUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual_r.csproj deleted file mode 100644 index 0742a6190f54..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual_ro.csproj deleted file mode 100644 index 790d50ee1bba..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar.Single.cs new file mode 100644 index 000000000000..51dd48ca7474 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareGreaterThanOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareGreaterThanOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanOrderedScalarSingle(); + var result = Sse.CompareGreaterThanOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] > right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar.cs deleted file mode 100644 index 84254af88e7b..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareGreaterThanOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareGreaterThanOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar_r.csproj deleted file mode 100644 index 7f2e72ed8406..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar_ro.csproj deleted file mode 100644 index 93ebf934286f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar.Single.cs new file mode 100644 index 000000000000..8598471ab6b4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareGreaterThanScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareGreaterThanScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareGreaterThanScalarSingle(); + var result = Sse.CompareGreaterThanScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar.cs deleted file mode 100644 index b07c68ef0be6..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareGreaterThanScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] > y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareGreaterThanScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar_r.csproj deleted file mode 100644 index 4f8e36d34dc9..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar_ro.csproj deleted file mode 100644 index 5d0f7880a027..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar.Single.cs new file mode 100644 index 000000000000..9a0d11e4491d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareGreaterThanUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareGreaterThanUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareGreaterThanUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareGreaterThanUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareGreaterThanUnorderedScalarSingle(); + var result = Sse.CompareGreaterThanUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareGreaterThanUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] > right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareGreaterThanUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar.cs deleted file mode 100644 index 8a0a8046854c..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareGreaterThanUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareGreaterThanUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareGreaterThanUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar_r.csproj deleted file mode 100644 index 6992a0d42b9e..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThanUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar_ro.csproj deleted file mode 100644 index c15d7d9193ba..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan_r.csproj deleted file mode 100644 index 425e4e92f345..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareGreaterThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan_ro.csproj deleted file mode 100644 index 0fd6ed7426d0..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs new file mode 100644 index 000000000000..5a13fe2d6d2e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanSingle() + { + var test = new SimpleBinaryOpTest__CompareLessThanSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareLessThanSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareLessThanSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareLessThanSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThan( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThan), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThan( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThan(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareLessThanSingle(); + var result = Sse.CompareLessThan(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThan(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThan)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.cs deleted file mode 100644 index 2bcd4689982f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareLessThan(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x < y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareLessThan failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs new file mode 100644 index 000000000000..11683c99723e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanOrEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareLessThanOrEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareLessThanOrEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareLessThanOrEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanOrEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanOrEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanOrEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareLessThanOrEqualSingle(); + var result = Sse.CompareLessThanOrEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanOrEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanOrEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.cs deleted file mode 100644 index 942aa1601823..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareLessThanOrEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x <= y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareLessThanOrEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.Single.cs new file mode 100644 index 000000000000..bb22aa7c5fa5 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanOrEqualOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanOrEqualOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrEqualOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanOrEqualOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanOrEqualOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrEqualOrderedScalarSingle(); + var result = Sse.CompareLessThanOrEqualOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanOrEqualOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] <= right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanOrEqualOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.cs deleted file mode 100644 index 1a2bb7487d9d..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareLessThanOrEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrEqualOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareLessThanOrEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrEqualOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar_r.csproj deleted file mode 100644 index 76681b4a804d..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar_ro.csproj deleted file mode 100644 index 6269bc65677a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar.Single.cs new file mode 100644 index 000000000000..89e451ddf0e7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanOrEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareLessThanOrEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareLessThanOrEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareLessThanOrEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanOrEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanOrEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanOrEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareLessThanOrEqualScalarSingle(); + var result = Sse.CompareLessThanOrEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanOrEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanOrEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar.cs deleted file mode 100644 index f8ba1b39d6ef..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareLessThanOrEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] <= y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareLessThanOrEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar_r.csproj deleted file mode 100644 index 08d703aa3b8e..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar_ro.csproj deleted file mode 100644 index 5739aeade31a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqualUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar.Single.cs new file mode 100644 index 000000000000..35d6708b6363 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanOrEqualUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanOrEqualUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrEqualUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanOrEqualUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanOrEqualUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrEqualUnorderedScalarSingle(); + var result = Sse.CompareLessThanOrEqualUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanOrEqualUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] <= right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanOrEqualUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar.cs deleted file mode 100644 index 22b201ca3819..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareLessThanOrEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrEqualUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareLessThanOrEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrEqualUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar_r.csproj deleted file mode 100644 index 3a8952ebfb32..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar_ro.csproj deleted file mode 100644 index eda9e1da5e5f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqualUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual_r.csproj deleted file mode 100644 index 1d1169149f81..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual_ro.csproj deleted file mode 100644 index f6e4c9116581..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar.Single.cs new file mode 100644 index 000000000000..9abafd999b9a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareLessThanOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareLessThanOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareLessThanOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareLessThanOrderedScalarSingle(); + var result = Sse.CompareLessThanOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] < right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar.cs deleted file mode 100644 index 2f0c15e2d725..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareLessThanOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareLessThanOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar_r.csproj deleted file mode 100644 index 422c95e9ffa3..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar_ro.csproj deleted file mode 100644 index 2f12ac5d19c7..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar.Single.cs new file mode 100644 index 000000000000..2a347dd93483 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareLessThanScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareLessThanScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareLessThanScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareLessThanScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareLessThanScalarSingle(); + var result = Sse.CompareLessThanScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar.cs deleted file mode 100644 index 5889b7caa3a2..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareLessThanScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] < y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareLessThanScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar_r.csproj deleted file mode 100644 index 623e3a4a370a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar_ro.csproj deleted file mode 100644 index f944465480da..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar.Single.cs new file mode 100644 index 000000000000..a1d5fefafecd --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareLessThanUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareLessThanUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareLessThanUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareLessThanUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareLessThanUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareLessThanUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareLessThanUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareLessThanUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareLessThanUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareLessThanUnorderedScalarSingle(); + var result = Sse.CompareLessThanUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareLessThanUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] < right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareLessThanUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar.cs deleted file mode 100644 index 3f64d00c07a8..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareLessThanUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 22, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareLessThanUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareLessThanUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar_r.csproj deleted file mode 100644 index ba058ba676d8..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThanUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar_ro.csproj deleted file mode 100644 index 9fbe2ebfd0cf..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan_r.csproj deleted file mode 100644 index ab46b2be74ad..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareLessThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan_ro.csproj deleted file mode 100644 index 481f6e19de3e..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs new file mode 100644 index 000000000000..b39660afe1fe --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareNotEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotEqualSingle(); + var result = Sse.CompareNotEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.cs deleted file mode 100644 index 58cba3946b99..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((x != y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareNotEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.Single.cs new file mode 100644 index 000000000000..4e0f2adf40f8 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotEqualOrderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareNotEqualOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareNotEqualOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareNotEqualOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareNotEqualOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotEqualOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotEqualOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotEqualOrderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotEqualOrderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareNotEqualOrderedScalarSingle(); + var result = Sse.CompareNotEqualOrderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotEqualOrderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] != right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotEqualOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.cs deleted file mode 100644 index f4cab7f2b53e..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareNotEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareNotEqualOrderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareNotEqualOrderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareNotEqualOrderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar_r.csproj deleted file mode 100644 index 15e11df3a5bf..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqualOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar_ro.csproj deleted file mode 100644 index 2b200a40cd85..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar.Single.cs new file mode 100644 index 000000000000..cd0942efe9c6 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareNotEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotEqualScalarSingle(); + var result = Sse.CompareNotEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar.cs deleted file mode 100644 index 8d35a733710d..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((x[0] != y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareNotEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar_r.csproj deleted file mode 100644 index f2e3b2ae20ff..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar_ro.csproj deleted file mode 100644 index c45a9e438d25..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqualUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar.Single.cs new file mode 100644 index 000000000000..36b04b4c8800 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar.Single.cs @@ -0,0 +1,196 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotEqualUnorderedScalarSingle() + { + var test = new BooleanComparisonOpTest__CompareNotEqualUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class BooleanComparisonOpTest__CompareNotEqualUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private BooleanComparisonOpTest__DataTable _dataTable; + + static BooleanComparisonOpTest__CompareNotEqualUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public BooleanComparisonOpTest__CompareNotEqualUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new BooleanComparisonOpTest__DataTable(_data1, _data2); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotEqualUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, result); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotEqualUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, (bool)(result)); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotEqualUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + ValidateResult(_clsVar1, _clsVar2, result); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotEqualUnorderedScalar(left, right); + + ValidateResult(left, right, result); + } + + public void RunLclFldScenario() + { + var test = new BooleanComparisonOpTest__CompareNotEqualUnorderedScalarSingle(); + var result = Sse.CompareNotEqualUnorderedScalar(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotEqualUnorderedScalar(_fld1, _fld2); + + ValidateResult(_fld1, _fld2, result); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, bool result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "") + { + if ((left[0] != right[0]) != result) + { + Succeeded = false; + + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotEqualUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar.cs deleted file mode 100644 index 5eccf193d4b3..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (!Sse.CompareNotEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareNotEqualUnorderedScalar failed positive test"); - testResult = Fail; - } - } - - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 1, -1, -50, 3 })) - { - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - - if (Sse.CompareNotEqualUnorderedScalar(vf1, vf2)) - { - Console.WriteLine("SSE CompareNotEqualUnorderedScalar failed negative test"); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - public TestTable(T[] a, T[] b) - { - this.inArray1 = a; - this.inArray2 = b; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar_r.csproj deleted file mode 100644 index e6e04f9ffe25..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqualUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar_ro.csproj deleted file mode 100644 index 9c9c2e144464..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqualUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual_r.csproj deleted file mode 100644 index 4a3e9fee3331..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual_ro.csproj deleted file mode 100644 index 95e82bf28e9d..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs new file mode 100644 index 000000000000..6d9bd2e08653 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotGreaterThanSingle() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotGreaterThanSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotGreaterThanSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotGreaterThan( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotGreaterThan), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotGreaterThan( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotGreaterThan(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanSingle(); + var result = Sse.CompareNotGreaterThan(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotGreaterThan(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotGreaterThan)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.cs deleted file mode 100644 index 6de6e06ac161..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotGreaterThan(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == (!(x > y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareNotGreaterThan failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs new file mode 100644 index 000000000000..29891c962173 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotGreaterThanOrEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotGreaterThanOrEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotGreaterThanOrEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotGreaterThanOrEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotGreaterThanOrEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle(); + var result = Sse.CompareNotGreaterThanOrEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotGreaterThanOrEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotGreaterThanOrEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.cs deleted file mode 100644 index 95fa95e3de40..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotGreaterThanOrEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == (!(x >= y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareNotGreaterThanOrEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.Single.cs new file mode 100644 index 000000000000..33a3687862a7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotGreaterThanOrEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotGreaterThanOrEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotGreaterThanOrEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotGreaterThanOrEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotGreaterThanOrEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualScalarSingle(); + var result = Sse.CompareNotGreaterThanOrEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotGreaterThanOrEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotGreaterThanOrEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.cs deleted file mode 100644 index 422f5e49c2bc..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotGreaterThanOrEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == (!(x[0] >= y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareNotGreaterThanOrEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar_r.csproj deleted file mode 100644 index 05f0db46b29e..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar_ro.csproj deleted file mode 100644 index 5790c6c3fc82..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual_r.csproj deleted file mode 100644 index 7e27cdc919fe..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual_ro.csproj deleted file mode 100644 index 11ddcf067c83..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThanScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar.Single.cs new file mode 100644 index 000000000000..f3d06f048db4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotGreaterThanScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotGreaterThanScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotGreaterThanScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotGreaterThanScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotGreaterThanScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotGreaterThanScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotGreaterThanScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotGreaterThanScalarSingle(); + var result = Sse.CompareNotGreaterThanScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotGreaterThanScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotGreaterThanScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar.cs deleted file mode 100644 index 2b69c0ef3be7..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotGreaterThanScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == (!(x[0] > y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareNotGreaterThanScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar_r.csproj deleted file mode 100644 index 63ec1e387eeb..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar_ro.csproj deleted file mode 100644 index 0ace8774af88..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan_r.csproj deleted file mode 100644 index e0ffef1cc403..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotGreaterThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan_ro.csproj deleted file mode 100644 index 4cdf11ae0fc4..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs new file mode 100644 index 000000000000..af354e4fe73a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotLessThanSingle() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotLessThanSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotLessThanSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotLessThan( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotLessThan), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotLessThan( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotLessThan(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanSingle(); + var result = Sse.CompareNotLessThan(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotLessThan(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotLessThan)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.cs deleted file mode 100644 index b0168cddee76..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotLessThan(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == (!(x < y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareNotLessThan failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs new file mode 100644 index 000000000000..cfe4d4d5d46e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotLessThanOrEqualSingle() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotLessThanOrEqual( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotLessThanOrEqual), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotLessThanOrEqual( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotLessThanOrEqual(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle(); + var result = Sse.CompareNotLessThanOrEqual(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotLessThanOrEqual(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotLessThanOrEqual)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.cs deleted file mode 100644 index b0ea5aa14b3b..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotLessThanOrEqual(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == (!(x <= y) ? -1 : 0))) - { - Console.WriteLine("SSE CompareNotLessThanOrEqual failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.Single.cs new file mode 100644 index 000000000000..b96ea1573a03 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotLessThanOrEqualScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotLessThanOrEqualScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotLessThanOrEqualScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotLessThanOrEqualScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotLessThanOrEqualScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualScalarSingle(); + var result = Sse.CompareNotLessThanOrEqualScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotLessThanOrEqualScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotLessThanOrEqualScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.cs deleted file mode 100644 index 4cbb9cbe3d19..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotLessThanOrEqualScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == (!(x[0] <= y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareNotLessThanOrEqualScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar_r.csproj deleted file mode 100644 index 2a314b927d8f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThanOrEqualScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar_ro.csproj deleted file mode 100644 index 5d31d0a48571..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqualScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual_r.csproj deleted file mode 100644 index 67ab4900a75c..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual_ro.csproj deleted file mode 100644 index 0876d2a86a13..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThanScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar.Single.cs new file mode 100644 index 000000000000..f308dab02136 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareNotLessThanScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareNotLessThanScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareNotLessThanScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareNotLessThanScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareNotLessThanScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareNotLessThanScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareNotLessThanScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareNotLessThanScalarSingle(); + var result = Sse.CompareNotLessThanScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareNotLessThanScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareNotLessThanScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar.cs deleted file mode 100644 index 090bdf21bfb6..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareNotLessThanScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == (!(x[0] < y[0]) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareNotLessThanScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar_r.csproj deleted file mode 100644 index a5289eecaa6f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThanScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar_ro.csproj deleted file mode 100644 index 4bbf0a5807ec..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan_r.csproj deleted file mode 100644 index c1ca05727e48..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareNotLessThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan_ro.csproj deleted file mode 100644 index 242acae30beb..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareOrdered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs new file mode 100644 index 000000000000..82cd8757740d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareOrderedSingle() + { + var test = new SimpleBinaryOpTest__CompareOrderedSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareOrderedSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareOrderedSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareOrderedSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareOrdered( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareOrdered), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareOrdered( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareOrdered(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareOrderedSingle(); + var result = Sse.CompareOrdered(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareOrdered(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((!float.IsNaN(left[0]) && !float.IsNaN(right[0])) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((!float.IsNaN(left[i]) && !float.IsNaN(right[i])) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareOrdered)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.cs deleted file mode 100644 index e743d276c031..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, float.NaN }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareOrdered(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((!float.IsNaN(x) && !float.IsNaN(y)) ? -1 : 0))) - { - Console.WriteLine("SSE CompareOrdered failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.Single.cs new file mode 100644 index 000000000000..42e018946a29 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareOrderedScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareOrderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareOrderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareOrderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareOrderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareOrderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareOrderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareOrderedScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareOrderedScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareOrderedScalarSingle(); + var result = Sse.CompareOrderedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareOrderedScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((!float.IsNaN(left[0]) && !float.IsNaN(right[0])) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareOrderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.cs deleted file mode 100644 index 690f8ceee42f..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareOrderedScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((!float.IsNaN(x[0]) && !float.IsNaN(y[0])) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareOrderedScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar_r.csproj deleted file mode 100644 index 6265a914cde6..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareOrderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar_ro.csproj deleted file mode 100644 index 1c3b4e342333..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareOrdered_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered_r.csproj deleted file mode 100644 index 995f8764ba18..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareOrdered_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered_ro.csproj deleted file mode 100644 index 60239f78e302..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareUnordered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs new file mode 100644 index 000000000000..434812197288 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareUnorderedSingle() + { + var test = new SimpleBinaryOpTest__CompareUnorderedSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareUnorderedSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareUnorderedSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareUnordered( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareUnordered), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareUnordered( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareUnordered(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareUnorderedSingle(); + var result = Sse.CompareUnordered(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareUnordered(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((float.IsNaN(left[0]) || float.IsNaN(right[0])) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(result[i]) != ((float.IsNaN(left[i]) || float.IsNaN(right[i])) ? -1 : 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareUnordered)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.cs deleted file mode 100644 index 5e7b55e6cae4..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, float.NaN }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareUnordered(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => BitConverter.SingleToInt32Bits(z) == ((float.IsNaN(x) || float.IsNaN(y)) ? -1 : 0))) - { - Console.WriteLine("SSE CompareUnordered failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.Single.cs new file mode 100644 index 000000000000..08d3c91dd6ec --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CompareUnorderedScalarSingle() + { + var test = new SimpleBinaryOpTest__CompareUnorderedScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__CompareUnorderedScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__CompareUnorderedScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.CompareUnorderedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.CompareUnorderedScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.CompareUnorderedScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.CompareUnorderedScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__CompareUnorderedScalarSingle(); + var result = Sse.CompareUnorderedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.CompareUnorderedScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(result[0]) != ((float.IsNaN(left[0]) || float.IsNaN(right[0])) ? -1 : 0)) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareUnorderedScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.cs deleted file mode 100644 index 2fc6cc777338..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.CompareUnorderedScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (BitConverter.SingleToInt32Bits(z[0]) == ((float.IsNaN(x[0]) || float.IsNaN(y[0])) ? -1 : 0)) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE CompareUnorderedScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar_r.csproj deleted file mode 100644 index 5aac2d9d63c5..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareUnorderedScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar_ro.csproj deleted file mode 100644 index 7de0eca71830..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnorderedScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareUnordered_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered_r.csproj deleted file mode 100644 index 884539f055ad..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/CompareUnordered_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered_ro.csproj deleted file mode 100644 index ef17dacfdcd2..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/Max.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs new file mode 100644 index 000000000000..5aa37e75274c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void MaxSingle() + { + var test = new SimpleBinaryOpTest__MaxSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__MaxSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__MaxSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__MaxSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.Max( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.Max), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.Max( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.Max(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__MaxSingle(); + var result = Sse.Max(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.Max(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(Math.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(Math.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.Max)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.cs deleted file mode 100644 index 54975156670d..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.Max(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => MathF.Max(x, y) == z)) - { - Console.WriteLine("SSE Max failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs new file mode 100644 index 000000000000..4edbc9c08831 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void MaxScalarSingle() + { + var test = new SimpleBinaryOpTest__MaxScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__MaxScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__MaxScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__MaxScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.MaxScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.MaxScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.MaxScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.MaxScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__MaxScalarSingle(); + var result = Sse.MaxScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.MaxScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(Math.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.MaxScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.cs deleted file mode 100644 index fd6f4a5216e0..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.MaxScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (z[0] == MathF.Max(x[0], y[0])) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE MaxScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar_r.csproj deleted file mode 100644 index ad5de2e6a4c4..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/MaxScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar_ro.csproj deleted file mode 100644 index b123cd2dc22b..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/Max_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max_r.csproj deleted file mode 100644 index ed084d26d247..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max_r.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - {CB11ECA5-6119-4E68-B036-7DFF909291F0} - Exe - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - ..\..\ - true - - - - - - - - False - - - - None - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max_ro.csproj deleted file mode 100644 index 58329685719a..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max_ro.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - {8109234B-3F93-4F71-8968-942201A100E6} - Exe - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - ..\..\ - true - - - - - - - - False - - - - None - True - - - - - - - - - - - \ No newline at end of file diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs new file mode 100644 index 000000000000..8a4d6269a9bf --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void MinSingle() + { + var test = new SimpleBinaryOpTest__MinSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__MinSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__MinSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__MinSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.Min( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.Min), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.Min( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.Min(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__MinSingle(); + var result = Sse.Min(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.Min(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(Math.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(Math.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.Min)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.cs deleted file mode 100644 index f07d5c067483..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.cs +++ /dev/null @@ -1,94 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 0 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.Min(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => MathF.Min(x, y) == z)) - { - Console.WriteLine("SSE Min failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - for (int i = 0; i < inArray1.Length; i++) - { - if (!check(inArray1[i], inArray2[i], outArray[i])) - { - return false; - } - } - return true; - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs new file mode 100644 index 000000000000..4f07b11f8efa --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs @@ -0,0 +1,216 @@ +// 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. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void MinScalarSingle() + { + var test = new SimpleBinaryOpTest__MinScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleBinaryOpTest__MinScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__MinScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__MinScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.MinScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.MinScalar), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.MinScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Sse.MinScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__MinScalarSingle(); + var result = Sse.MinScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.MinScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128 left, Vector128 right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(Math.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.MinScalar)}: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.cs deleted file mode 100644 index 5f8a0aaef698..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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.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; - - static unsafe int Main(string[] args) - { - int testResult = Pass; - - if (Sse.IsSupported) - { - using (TestTable floatTable = new TestTable(new float[4] { 1, -5, 100, 0 }, new float[4] { 22, -1, -50, 3 }, new float[4])) - { - - var vf1 = Unsafe.Read>(floatTable.inArray1Ptr); - var vf2 = Unsafe.Read>(floatTable.inArray2Ptr); - var vf3 = Sse.MinScalar(vf1, vf2); - Unsafe.Write(floatTable.outArrayPtr, vf3); - - if (!floatTable.CheckResult((x, y, z) => (z[0] == MathF.Min(x[0], y[0])) && - (z[1] == x[1]) && (z[2] == x[2]) && (z[3] == x[3]))) - { - Console.WriteLine("SSE MinScalar failed on float:"); - foreach (var item in floatTable.outArray) - { - Console.Write(item + ", "); - } - Console.WriteLine(); - testResult = Fail; - } - } - } - - - return testResult; - } - - public unsafe struct TestTable : IDisposable where T : struct - { - public T[] inArray1; - public T[] inArray2; - public T[] outArray; - - public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer(); - public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer(); - public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); - - GCHandle inHandle1; - GCHandle inHandle2; - GCHandle outHandle; - public TestTable(T[] a, T[] b, T[] c) - { - this.inArray1 = a; - this.inArray2 = b; - this.outArray = c; - - inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned); - inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned); - outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); - } - public bool CheckResult(Func check) - { - return check(inArray1, inArray2, outArray); - } - - public void Dispose() - { - inHandle1.Free(); - inHandle2.Free(); - outHandle.Free(); - } - } - - } -} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar_Ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar_Ro.csproj deleted file mode 100644 index 8317c24e0a7c..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar_Ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/MinScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar_r.csproj deleted file mode 100644 index b54199ed0245..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/Min_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min_r.csproj deleted file mode 100644 index 5b815b2561dc..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min_r.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/Min_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min_ro.csproj deleted file mode 100644 index d1817e31c2e8..000000000000 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min_ro.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - - 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/Sse/Program.Sse.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Program.Sse.cs index 5e94e62bef78..035861040298 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Program.Sse.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Program.Sse.cs @@ -16,8 +16,48 @@ static Program() ["AddScalar.Single"] = AddScalarSingle, ["And.Single"] = AndSingle, ["AndNot.Single"] = AndNotSingle, + ["CompareEqual.Single"] = CompareEqualSingle, + ["CompareEqualScalar.Single"] = CompareEqualScalarSingle, + ["CompareEqualOrderedScalar.Single"] = CompareEqualOrderedScalarSingle, + ["CompareEqualUnorderedScalar.Single"] = CompareEqualUnorderedScalarSingle, + ["CompareGreaterThan.Single"] = CompareGreaterThanSingle, + ["CompareGreaterThanScalar.Single"] = CompareGreaterThanScalarSingle, + ["CompareGreaterThanOrderedScalar.Single"] = CompareGreaterThanOrderedScalarSingle, + ["CompareGreaterThanUnorderedScalar.Single"] = CompareGreaterThanUnorderedScalarSingle, + ["CompareGreaterThanOrEqual.Single"] = CompareGreaterThanOrEqualSingle, + ["CompareGreaterThanOrEqualScalar.Single"] = CompareGreaterThanOrEqualScalarSingle, + ["CompareGreaterThanOrEqualOrderedScalar.Single"] = CompareGreaterThanOrEqualOrderedScalarSingle, + ["CompareGreaterThanOrEqualUnorderedScalar.Single"] = CompareGreaterThanOrEqualUnorderedScalarSingle, + ["CompareLessThan.Single"] = CompareLessThanSingle, + ["CompareLessThanScalar.Single"] = CompareLessThanScalarSingle, + ["CompareLessThanOrderedScalar.Single"] = CompareLessThanOrderedScalarSingle, + ["CompareLessThanUnorderedScalar.Single"] = CompareLessThanUnorderedScalarSingle, + ["CompareLessThanOrEqual.Single"] = CompareLessThanOrEqualSingle, + ["CompareLessThanOrEqualScalar.Single"] = CompareLessThanOrEqualScalarSingle, + ["CompareLessThanOrEqualOrderedScalar.Single"] = CompareLessThanOrEqualOrderedScalarSingle, + ["CompareLessThanOrEqualUnorderedScalar.Single"] = CompareLessThanOrEqualUnorderedScalarSingle, + ["CompareNotEqual.Single"] = CompareNotEqualSingle, + ["CompareNotEqualScalar.Single"] = CompareNotEqualScalarSingle, + ["CompareNotEqualOrderedScalar.Single"] = CompareNotEqualOrderedScalarSingle, + ["CompareNotEqualUnorderedScalar.Single"] = CompareNotEqualUnorderedScalarSingle, + ["CompareNotGreaterThan.Single"] = CompareNotGreaterThanSingle, + ["CompareNotGreaterThanScalar.Single"] = CompareNotGreaterThanScalarSingle, + ["CompareNotGreaterThanOrEqual.Single"] = CompareNotGreaterThanOrEqualSingle, + ["CompareNotGreaterThanOrEqualScalar.Single"] = CompareNotGreaterThanOrEqualScalarSingle, + ["CompareNotLessThan.Single"] = CompareNotLessThanSingle, + ["CompareNotLessThanScalar.Single"] = CompareNotLessThanScalarSingle, + ["CompareNotLessThanOrEqual.Single"] = CompareNotLessThanOrEqualSingle, + ["CompareNotLessThanOrEqualScalar.Single"] = CompareNotLessThanOrEqualScalarSingle, + ["CompareOrdered.Single"] = CompareOrderedSingle, + ["CompareOrderedScalar.Single"] = CompareOrderedScalarSingle, + ["CompareUnordered.Single"] = CompareUnorderedSingle, + ["CompareUnorderedScalar.Single"] = CompareUnorderedScalarSingle, ["Divide.Single"] = DivideSingle, ["DivideScalar.Single"] = DivideScalarSingle, + ["Max.Single"] = MaxSingle, + ["MaxScalar.Single"] = MaxScalarSingle, + ["Min.Single"] = MinSingle, + ["MinScalar.Single"] = MinScalarSingle, ["Multiply.Single"] = MultiplySingle, ["MultiplyScalar.Single"] = MultiplyScalarSingle, ["Or.Single"] = OrSingle, diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj index 27ad4842f2e2..ee3966d9b2a8 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj @@ -31,8 +31,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -40,6 +80,7 @@ + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj index 31d521f8cc73..946557677a63 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj @@ -31,8 +31,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -40,6 +80,7 @@ +