diff options
author | Fei Peng <fei.peng@intel.com> | 2018-02-22 00:34:20 -0800 |
---|---|---|
committer | Tanner Gooding <tagoo@outlook.com> | 2018-02-26 19:08:13 -0800 |
commit | ec78ba4a4467fff7ca069a3123788c96eeca2ebc (patch) | |
tree | d5073efbd79b606ef8453aaf7f1dc2a6b9d10a86 /tests/src/JIT | |
parent | a910601369a4835fc1184bd7ac0640813192dc7e (diff) | |
download | coreclr-ec78ba4a4467fff7ca069a3123788c96eeca2ebc.tar.gz coreclr-ec78ba4a4467fff7ca069a3123788c96eeca2ebc.tar.bz2 coreclr-ec78ba4a4467fff7ca069a3123788c96eeca2ebc.zip |
Add tests/templates for AVX2/SSE2 shift intrinsics
Diffstat (limited to 'tests/src/JIT')
96 files changed, 28231 insertions, 2 deletions
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj index b5483cdedd..178f5cd65e 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj @@ -75,6 +75,50 @@ <Compile Include="Or.UInt16.cs" /> <Compile Include="Or.UInt32.cs" /> <Compile Include="Or.UInt64.cs" /> + <Compile Include="ShiftLeftLogical.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.1.cs" /> + <Compile Include="ShiftLeftLogical.Int16.16.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.16.cs" /> + <Compile Include="ShiftLeftLogical.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.32.cs" /> + <Compile Include="ShiftLeftLogical.Int64.64.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightLogical.Int16.1.cs" /> + <Compile Include="ShiftRightLogical.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical.Int32.1.cs" /> + <Compile Include="ShiftRightLogical.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical.Int64.1.cs" /> + <Compile Include="ShiftRightLogical.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical.Int16.16.cs" /> + <Compile Include="ShiftRightLogical.UInt16.16.cs" /> + <Compile Include="ShiftRightLogical.Int32.32.cs" /> + <Compile Include="ShiftRightLogical.UInt32.32.cs" /> + <Compile Include="ShiftRightLogical.Int64.64.cs" /> + <Compile Include="ShiftRightLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.16.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt64.1.cs" /> <Compile Include="Subtract.Byte.cs" /> <Compile Include="Subtract.Int16.cs" /> <Compile Include="Subtract.Int32.cs" /> @@ -94,7 +138,8 @@ <Compile Include="Program.Avx2.cs" /> <Compile Include="..\Shared\Program.cs" /> <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" /> - <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" /> + <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" /> + <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj index bf0dc985e8..c928b08268 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj @@ -75,6 +75,50 @@ <Compile Include="Or.UInt16.cs" /> <Compile Include="Or.UInt32.cs" /> <Compile Include="Or.UInt64.cs" /> + <Compile Include="ShiftLeftLogical.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.1.cs" /> + <Compile Include="ShiftLeftLogical.Int16.16.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.16.cs" /> + <Compile Include="ShiftLeftLogical.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.32.cs" /> + <Compile Include="ShiftLeftLogical.Int64.64.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightLogical.Int16.1.cs" /> + <Compile Include="ShiftRightLogical.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical.Int32.1.cs" /> + <Compile Include="ShiftRightLogical.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical.Int64.1.cs" /> + <Compile Include="ShiftRightLogical.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical.Int16.16.cs" /> + <Compile Include="ShiftRightLogical.UInt16.16.cs" /> + <Compile Include="ShiftRightLogical.Int32.32.cs" /> + <Compile Include="ShiftRightLogical.UInt32.32.cs" /> + <Compile Include="ShiftRightLogical.Int64.64.cs" /> + <Compile Include="ShiftRightLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.16.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt64.1.cs" /> <Compile Include="Subtract.Byte.cs" /> <Compile Include="Subtract.Int16.cs" /> <Compile Include="Subtract.Int32.cs" /> @@ -95,6 +139,7 @@ <Compile Include="..\Shared\Program.cs" /> <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" /> <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" /> + <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs index df966962b8..c89da0a534 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs @@ -76,6 +76,50 @@ namespace JIT.HardwareIntrinsics.X86 ["Xor.UInt16"] = XorUInt16, ["Xor.UInt32"] = XorUInt32, ["Xor.UInt64"] = XorUInt64, + ["ShiftLeftLogical.Int16.1"] = ShiftLeftLogicalInt161, + ["ShiftLeftLogical.UInt16.1"] = ShiftLeftLogicalUInt161, + ["ShiftLeftLogical.Int32.1"] = ShiftLeftLogicalInt321, + ["ShiftLeftLogical.UInt32.1"] = ShiftLeftLogicalUInt321, + ["ShiftLeftLogical.Int64.1"] = ShiftLeftLogicalInt641, + ["ShiftLeftLogical.UInt64.1"] = ShiftLeftLogicalUInt641, + ["ShiftLeftLogical.Int16.16"] = ShiftLeftLogicalInt1616, + ["ShiftLeftLogical.UInt16.16"] = ShiftLeftLogicalUInt1616, + ["ShiftLeftLogical.Int32.32"] = ShiftLeftLogicalInt3232, + ["ShiftLeftLogical.UInt32.32"] = ShiftLeftLogicalUInt3232, + ["ShiftLeftLogical.Int64.64"] = ShiftLeftLogicalInt6464, + ["ShiftLeftLogical.UInt64.64"] = ShiftLeftLogicalUInt6464, + ["ShiftRightLogical.Int16.1"] = ShiftRightLogicalInt161, + ["ShiftRightLogical.UInt16.1"] = ShiftRightLogicalUInt161, + ["ShiftRightLogical.Int32.1"] = ShiftRightLogicalInt321, + ["ShiftRightLogical.UInt32.1"] = ShiftRightLogicalUInt321, + ["ShiftRightLogical.Int64.1"] = ShiftRightLogicalInt641, + ["ShiftRightLogical.UInt64.1"] = ShiftRightLogicalUInt641, + ["ShiftRightLogical.Int16.16"] = ShiftRightLogicalInt1616, + ["ShiftRightLogical.UInt16.16"] = ShiftRightLogicalUInt1616, + ["ShiftRightLogical.Int32.32"] = ShiftRightLogicalInt3232, + ["ShiftRightLogical.UInt32.32"] = ShiftRightLogicalUInt3232, + ["ShiftRightLogical.Int64.64"] = ShiftRightLogicalInt6464, + ["ShiftRightLogical.UInt64.64"] = ShiftRightLogicalUInt6464, + ["ShiftRightArithmetic.Int16.1"] = ShiftRightArithmeticInt161, + ["ShiftRightArithmetic.Int32.1"] = ShiftRightArithmeticInt321, + ["ShiftRightArithmetic.Int16.16"] = ShiftRightArithmeticInt1616, + ["ShiftRightArithmetic.Int32.32"] = ShiftRightArithmeticInt3232, + ["ShiftLeftLogical128BitLane.SByte.1"] = ShiftLeftLogical128BitLaneSByte1, + ["ShiftLeftLogical128BitLane.Byte.1"] = ShiftLeftLogical128BitLaneByte1, + ["ShiftLeftLogical128BitLane.Int16.1"] = ShiftLeftLogical128BitLaneInt161, + ["ShiftLeftLogical128BitLane.UInt16.1"] = ShiftLeftLogical128BitLaneUInt161, + ["ShiftLeftLogical128BitLane.Int32.1"] = ShiftLeftLogical128BitLaneInt321, + ["ShiftLeftLogical128BitLane.UInt32.1"] = ShiftLeftLogical128BitLaneUInt321, + ["ShiftLeftLogical128BitLane.Int64.1"] = ShiftLeftLogical128BitLaneInt641, + ["ShiftLeftLogical128BitLane.UInt64.1"] = ShiftLeftLogical128BitLaneUInt641, + ["ShiftRightLogical128BitLane.SByte.1"] = ShiftRightLogical128BitLaneSByte1, + ["ShiftRightLogical128BitLane.Byte.1"] = ShiftRightLogical128BitLaneByte1, + ["ShiftRightLogical128BitLane.Int16.1"] = ShiftRightLogical128BitLaneInt161, + ["ShiftRightLogical128BitLane.UInt16.1"] = ShiftRightLogical128BitLaneUInt161, + ["ShiftRightLogical128BitLane.Int32.1"] = ShiftRightLogical128BitLaneInt321, + ["ShiftRightLogical128BitLane.UInt32.1"] = ShiftRightLogical128BitLaneUInt321, + ["ShiftRightLogical128BitLane.Int64.1"] = ShiftRightLogical128BitLaneInt641, + ["ShiftRightLogical128BitLane.UInt64.1"] = ShiftRightLogical128BitLaneUInt641, }; } } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.1.cs new file mode 100644 index 0000000000..007043b604 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt161(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.16.cs new file mode 100644 index 0000000000..d43acc0c09 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt1616() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt1616 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt1616(); + var result = Avx2.ShiftLeftLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.1.cs new file mode 100644 index 0000000000..a6e39e42dc --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt321(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.32.cs new file mode 100644 index 0000000000..d3628de45b --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt3232() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt3232 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt3232(); + var result = Avx2.ShiftLeftLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.1.cs new file mode 100644 index 0000000000..98488c3274 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt641(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if ((long)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((long)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.64.cs new file mode 100644 index 0000000000..c5e5350ae3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.Int64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt6464() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt6464 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt6464(); + var result = Avx2.ShiftLeftLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.1.cs new file mode 100644 index 0000000000..77cb0e8e41 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt161(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if ((ushort)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ushort)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.16.cs new file mode 100644 index 0000000000..1d87bb6bd5 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt1616() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt1616 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt1616(); + var result = Avx2.ShiftLeftLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.1.cs new file mode 100644 index 0000000000..e89589eea4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt321(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if ((uint)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((uint)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.32.cs new file mode 100644 index 0000000000..bb0c7e779a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt3232() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt3232 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt3232(); + var result = Avx2.ShiftLeftLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0!= result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.1.cs new file mode 100644 index 0000000000..488943b9cb --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt641(); + var result = Avx2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if ((ulong)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ulong)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.64.cs new file mode 100644 index 0000000000..81ccc1d901 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical.UInt64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt6464() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt6464 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt6464(); + var result = Avx2.ShiftLeftLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Byte.1.cs new file mode 100644 index 0000000000..578b530618 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Byte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneByte1() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Byte); + private const int RetElementCount = VectorSize / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector256<Byte> _clsVar; + + private Vector256<Byte> _fld; + + private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 0) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 16 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<Byte>(Vector256<Byte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int16.1.cs new file mode 100644 index 0000000000..f320ee1091 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int32.1.cs new file mode 100644 index 0000000000..913d5e29b0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int64.1.cs new file mode 100644 index 0000000000..90f853913e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.SByte.1.cs new file mode 100644 index 0000000000..a9a9b05a5e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.SByte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneSByte1() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(SByte); + private const int RetElementCount = VectorSize / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector256<SByte> _clsVar; + + private Vector256<SByte> _fld; + + private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 0) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 16 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<SByte>(Vector256<SByte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt16.1.cs new file mode 100644 index 0000000000..8aff89a2be --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt32.1.cs new file mode 100644 index 0000000000..c2acdd5e0a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt64.1.cs new file mode 100644 index 0000000000..28ae6e0ae1 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftLeftLogical128BitLane.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftLeftLogical128BitLane( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641(); + var result = Avx2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftLeftLogical128BitLane)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.1.cs new file mode 100644 index 0000000000..bdf3ff20b8 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightArithmetic( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt161(); + var result = Avx2.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightArithmetic)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.16.cs new file mode 100644 index 0000000000..20baccec61 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt1616 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightArithmetic( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightArithmetic( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt1616(); + var result = Avx2.ShiftRightArithmetic(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightArithmetic(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 15) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 15) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightArithmetic)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.1.cs new file mode 100644 index 0000000000..981aff6b64 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightArithmetic( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt321(); + var result = Avx2.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightArithmetic)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.32.cs new file mode 100644 index 0000000000..1cf60a09ef --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmetic.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt3232 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightArithmetic( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightArithmetic( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightArithmetic), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightArithmetic( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt3232(); + var result = Avx2.ShiftRightArithmetic(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightArithmetic(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 31) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 31) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightArithmetic)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.1.cs new file mode 100644 index 0000000000..52f8d6dd2f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt161(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.16.cs new file mode 100644 index 0000000000..e49aa1070d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt1616 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt1616(); + var result = Avx2.ShiftRightLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.1.cs new file mode 100644 index 0000000000..3cfcad2671 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt321(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.32.cs new file mode 100644 index 0000000000..e961421ec0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt3232 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt3232(); + var result = Avx2.ShiftRightLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.1.cs new file mode 100644 index 0000000000..cc59a8d4a0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt641(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if ((long)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((long)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.64.cs new file mode 100644 index 0000000000..12fde26463 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.Int64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt6464() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt6464 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt6464(); + var result = Avx2.ShiftRightLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.1.cs new file mode 100644 index 0000000000..a7a261bab8 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt161(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if ((ushort)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ushort)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.16.cs new file mode 100644 index 0000000000..a7a1e1ca75 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt1616 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt1616(); + var result = Avx2.ShiftRightLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.1.cs new file mode 100644 index 0000000000..286a458ea2 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt321(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if ((uint)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((uint)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.32.cs new file mode 100644 index 0000000000..8d83525093 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt3232 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt3232(); + var result = Avx2.ShiftRightLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0!= result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.1.cs new file mode 100644 index 0000000000..c0a3ad47d3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt641(); + var result = Avx2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if ((ulong)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ulong)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.64.cs new file mode 100644 index 0000000000..e9f341d6c2 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical.UInt64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt6464() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt6464 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt6464(); + var result = Avx2.ShiftRightLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Byte.1.cs new file mode 100644 index 0000000000..86fe0427bd --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Byte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneByte1() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Byte); + private const int RetElementCount = VectorSize / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector256<Byte> _clsVar; + + private Vector256<Byte> _fld; + + private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 8) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 31 || i == 15 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<Byte>(Vector256<Byte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int16.1.cs new file mode 100644 index 0000000000..ac314d3065 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256<Int16> _clsVar; + + private Vector256<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 7 || i == 15 ? result[i] != 0 : result[i] != 2048)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<Int16>(Vector256<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int32.1.cs new file mode 100644 index 0000000000..e7bca796d5 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256<Int32> _clsVar; + + private Vector256<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 134217728) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 3 || i == 7 ? result[i] != 0 : result[i] != 134217728)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<Int32>(Vector256<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int64.1.cs new file mode 100644 index 0000000000..85cdea3c7d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256<Int64> _clsVar; + + private Vector256<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 576460752303423488L) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 2 ? result[i] != 576460752303423488L : result[i] != 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<Int64>(Vector256<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.SByte.1.cs new file mode 100644 index 0000000000..a419e1ad1f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.SByte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneSByte1() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(SByte); + private const int RetElementCount = VectorSize / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector256<SByte> _clsVar; + + private Vector256<SByte> _fld; + + private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 8) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 31 || i == 15 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<SByte>(Vector256<SByte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt16.1.cs new file mode 100644 index 0000000000..d08ec3fee7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256<UInt16> _clsVar; + + private Vector256<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 7 || i == 15 ? result[i] != 0 : result[i] != 2048)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<UInt16>(Vector256<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt32.1.cs new file mode 100644 index 0000000000..f6a02a0829 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256<UInt32> _clsVar; + + private Vector256<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 134217728) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 3 || i == 7 ? result[i] != 0 : result[i] != 134217728)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<UInt32>(Vector256<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt64.1.cs new file mode 100644 index 0000000000..679327cd57 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightLogical128BitLane.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641 + { + private const int VectorSize = 32; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256<UInt64> _clsVar; + + private Vector256<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx2.ShiftRightLogical128BitLane( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx2).GetMethod(nameof(Avx2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector256<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641(); + var result = Avx2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 576460752303423488UL) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 2 ? result[i] != 576460752303423488UL : result[i] != 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ShiftRightLogical128BitLane)}<UInt64>(Vector256<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx index 4351de6d9b..5950e9e09c 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx @@ -164,6 +164,53 @@ private static readonly (string templateFileName, string[] templateData)[] Sse2I ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Vector128", "UInt16", "Vector128", "UInt16", "Vector128", "UInt16", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] ^ right[0]) != result[0]", "(ushort)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Vector128", "UInt32", "Vector128", "UInt32", "Vector128", "UInt32", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] ^ right[0]) != result[0]", "(uint)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Vector128", "UInt64", "Vector128", "UInt64", "Vector128", "UInt64", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] ^ right[0]) != result[0]", "(ulong)(left[i] ^ right[i]) != result[i]"}), + + // IMM intrinsics + // TemplateName Isa, LoadIsa, Method, RetVectorType, RetBaseType, Op1VectorType, Op1BaseType, IMM, VectorSize, NextValueOp1, ValidateFirstResult, ValidateRemainingResults + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int16", "Vector128", "Int16", "1", "16", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] << 1) != result[0]", "(short)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt16", "Vector128", "UInt16", "1", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(firstOp[0] << 1) != result[0]", "(ushort)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int32", "Vector128", "Int32", "1", "16", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] << 1) != result[0]", "(int)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt32", "Vector128", "UInt32", "1", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(firstOp[0] << 1) != result[0]", "(uint)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int64", "Vector128", "Int64", "1", "16", "(long)(random.Next(0, int.MaxValue))", "(long)(firstOp[0] << 1) != result[0]", "(long)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt64", "Vector128", "UInt64", "1", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(firstOp[0] << 1) != result[0]", "(ulong)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int16", "Vector128", "Int16", "16", "16", "(short)(random.Next(0, short.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt16", "Vector128", "UInt16", "16", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int32", "Vector128", "Int32", "32", "16", "(int)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt32", "Vector128", "UInt32", "32", "16", "(uint)(random.Next(0, int.MaxValue))", "0 != result[0]", "0!= result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "Int64", "Vector128", "Int64", "64", "16", "(long)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical", "Vector128", "UInt64", "Vector128", "UInt64", "64", "16", "(ulong)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int16", "Vector128", "Int16", "1", "16", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 1) != result[0]", "(short)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt16", "Vector128", "UInt16", "1", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(firstOp[0] >> 1) != result[0]", "(ushort)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int32", "Vector128", "Int32", "1", "16", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 1) != result[0]", "(int)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt32", "Vector128", "UInt32", "1", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(firstOp[0] >> 1) != result[0]", "(uint)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int64", "Vector128", "Int64", "1", "16", "(long)(random.Next(0, int.MaxValue))", "(long)(firstOp[0] >> 1) != result[0]", "(long)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt64", "Vector128", "UInt64", "1", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(firstOp[0] >> 1) != result[0]", "(ulong)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int16", "Vector128", "Int16", "16", "16", "(short)(random.Next(0, short.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt16", "Vector128", "UInt16", "16", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int32", "Vector128", "Int32", "32", "16", "(int)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt32", "Vector128", "UInt32", "32", "16", "(uint)(random.Next(0, int.MaxValue))", "0 != result[0]", "0!= result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "Int64", "Vector128", "Int64", "64", "16", "(long)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical", "Vector128", "UInt64", "Vector128", "UInt64", "64", "16", "(ulong)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightArithmetic", "Vector128", "Int16", "Vector128", "Int16", "1", "16", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 1) != result[0]", "(short)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightArithmetic", "Vector128", "Int32", "Vector128", "Int32", "1", "16", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 1) != result[0]", "(int)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightArithmetic", "Vector128", "Int16", "Vector128", "Int16", "16", "16", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 15) != result[0]", "(short)(firstOp[i] >> 15) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightArithmetic", "Vector128", "Int32", "Vector128", "Int32", "32", "16", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 31) != result[0]", "(int)(firstOp[i] >> 31) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "SByte", "Vector128", "SByte", "1", "16", "(sbyte)8", "result[0] != 0", "result[i] != 8"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "Byte", "Vector128", "Byte", "1", "16", "(byte)8", "result[0] != 0", "result[i] != 8"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "Int16", "Vector128", "Int16", "1", "16", "(short)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "UInt16", "Vector128", "UInt16", "1", "16", "(ushort)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "Int32", "Vector128", "Int32", "1", "16", "(int)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "UInt32", "Vector128", "UInt32", "1", "16", "(uint)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "Int64", "Vector128", "Int64", "1", "16", "(long)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftLeftLogical128BitLane", "Vector128", "UInt64", "Vector128", "UInt64", "1", "16", "(ulong)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "SByte", "Vector128", "SByte", "1", "16", "(sbyte)8", "result[0] != 8", "(i == 15 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "Byte", "Vector128", "Byte", "1", "16", "(byte)8", "result[0] != 8", "(i == 15 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "Int16", "Vector128", "Int16", "1", "16", "(short)8", "result[0] != 2048", "(i == 7 ? result[i] != 0 : result[i] != 2048)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "UInt16", "Vector128", "UInt16", "1", "16", "(ushort)8", "result[0] != 2048", "(i == 7 ? result[i] != 0 : result[i] != 2048)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "Int32", "Vector128", "Int32", "1", "16", "(int)8", "result[0] != 134217728", "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "UInt32", "Vector128", "UInt32", "1", "16", "(uint)8", "result[0] != 134217728", "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "Int64", "Vector128", "Int64", "1", "16", "(long)8", "result[0] != 576460752303423488L", "(result[i] != 0)"}), + ("ImmUnOpTest.template", new string[] { "Sse2", "Sse2", "ShiftRightLogical128BitLane", "Vector128", "UInt64", "Vector128", "UInt64", "1", "16", "(ulong)8", "result[0] != 576460752303423488UL", "(result[i] != 0)"}), }; private static readonly (string templateFileName, string[] templateData)[] Sse3Inputs = new [] @@ -309,6 +356,53 @@ private static readonly (string templateFileName, string[] templateData)[] Avx2I ("SimpleBinOpTest.template", new string[] { "Avx2", "Avx", "Xor", "Vector256", "UInt16", "Vector256", "UInt16", "Vector256", "UInt16", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] ^ right[0]) != result[0]", "(ushort)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new string[] { "Avx2", "Avx", "Xor", "Vector256", "UInt32", "Vector256", "UInt32", "Vector256", "UInt32", "32", "(uint)(random.Next(0, int.MaxValue))", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] ^ right[0]) != result[0]", "(uint)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new string[] { "Avx2", "Avx", "Xor", "Vector256", "UInt64", "Vector256", "UInt64", "Vector256", "UInt64", "32", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] ^ right[0]) != result[0]", "(ulong)(left[i] ^ right[i]) != result[i]"}), + + // IMM intrinsics + // TemplateName Isa, LoadIsa, Method, RetVectorType, RetBaseType, Op1VectorType, Op1BaseType, IMM, VectorSize, NextValueOp1, ValidateFirstResult, ValidateRemainingResults + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int16", "Vector256", "Int16", "1", "32", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] << 1) != result[0]", "(short)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt16", "Vector256", "UInt16", "1", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(firstOp[0] << 1) != result[0]", "(ushort)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int32", "Vector256", "Int32", "1", "32", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] << 1) != result[0]", "(int)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt32", "Vector256", "UInt32", "1", "32", "(uint)(random.Next(0, int.MaxValue))", "(uint)(firstOp[0] << 1) != result[0]", "(uint)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int64", "Vector256", "Int64", "1", "32", "(long)(random.Next(0, int.MaxValue))", "(long)(firstOp[0] << 1) != result[0]", "(long)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt64", "Vector256", "UInt64", "1", "32", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(firstOp[0] << 1) != result[0]", "(ulong)(firstOp[i] << 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int16", "Vector256", "Int16", "16", "32", "(short)(random.Next(0, short.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt16", "Vector256", "UInt16", "16", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int32", "Vector256", "Int32", "32", "32", "(int)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt32", "Vector256", "UInt32", "32", "32", "(uint)(random.Next(0, int.MaxValue))", "0 != result[0]", "0!= result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "Int64", "Vector256", "Int64", "64", "32", "(long)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical", "Vector256", "UInt64", "Vector256", "UInt64", "64", "32", "(ulong)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int16", "Vector256", "Int16", "1", "32", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 1) != result[0]", "(short)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt16", "Vector256", "UInt16", "1", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(firstOp[0] >> 1) != result[0]", "(ushort)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int32", "Vector256", "Int32", "1", "32", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 1) != result[0]", "(int)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt32", "Vector256", "UInt32", "1", "32", "(uint)(random.Next(0, int.MaxValue))", "(uint)(firstOp[0] >> 1) != result[0]", "(uint)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int64", "Vector256", "Int64", "1", "32", "(long)(random.Next(0, int.MaxValue))", "(long)(firstOp[0] >> 1) != result[0]", "(long)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt64", "Vector256", "UInt64", "1", "32", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(firstOp[0] >> 1) != result[0]", "(ulong)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int16", "Vector256", "Int16", "16", "32", "(short)(random.Next(0, short.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt16", "Vector256", "UInt16", "16", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int32", "Vector256", "Int32", "32", "32", "(int)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt32", "Vector256", "UInt32", "32", "32", "(uint)(random.Next(0, int.MaxValue))", "0 != result[0]", "0!= result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "Int64", "Vector256", "Int64", "64", "32", "(long)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical", "Vector256", "UInt64", "Vector256", "UInt64", "64", "32", "(ulong)(random.Next(0, int.MaxValue))", "0 != result[0]", "0 != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightArithmetic", "Vector256", "Int16", "Vector256", "Int16", "1", "32", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 1) != result[0]", "(short)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightArithmetic", "Vector256", "Int32", "Vector256", "Int32", "1", "32", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 1) != result[0]", "(int)(firstOp[i] >> 1) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightArithmetic", "Vector256", "Int16", "Vector256", "Int16", "16", "32", "(short)(random.Next(0, short.MaxValue))", "(short)(firstOp[0] >> 15) != result[0]", "(short)(firstOp[i] >> 15) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightArithmetic", "Vector256", "Int32", "Vector256", "Int32", "32", "32", "(int)(random.Next(0, int.MaxValue))", "(int)(firstOp[0] >> 31) != result[0]", "(int)(firstOp[i] >> 31) != result[i]"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "SByte", "Vector256", "SByte", "1", "32", "(sbyte)8", "result[0] != 0", "(i == 16 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "Byte", "Vector256", "Byte", "1", "32", "(byte)8", "result[0] != 0", "(i == 16 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "Int16", "Vector256", "Int16", "1", "32", "(short)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "UInt16", "Vector256", "UInt16", "1", "32", "(ushort)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "Int32", "Vector256", "Int32", "1", "32", "(int)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "UInt32", "Vector256", "UInt32", "1", "32", "(uint)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "Int64", "Vector256", "Int64", "1", "32", "(long)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftLeftLogical128BitLane", "Vector256", "UInt64", "Vector256", "UInt64", "1", "32", "(ulong)8", "result[0] != 2048", "result[i] != 2048"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "SByte", "Vector256", "SByte", "1", "32", "(sbyte)8", "result[0] != 8", "(i == 31 || i == 15 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "Byte", "Vector256", "Byte", "1", "32", "(byte)8", "result[0] != 8", "(i == 31 || i == 15 ? result[i] != 0 : result[i] != 8)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "Int16", "Vector256", "Int16", "1", "32", "(short)8", "result[0] != 2048", "(i == 7 || i == 15 ? result[i] != 0 : result[i] != 2048)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "UInt16", "Vector256", "UInt16", "1", "32", "(ushort)8", "result[0] != 2048", "(i == 7 || i == 15 ? result[i] != 0 : result[i] != 2048)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "Int32", "Vector256", "Int32", "1", "32", "(int)8", "result[0] != 134217728", "(i == 3 || i == 7 ? result[i] != 0 : result[i] != 134217728)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "UInt32", "Vector256", "UInt32", "1", "32", "(uint)8", "result[0] != 134217728", "(i == 3 || i == 7 ? result[i] != 0 : result[i] != 134217728)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "Int64", "Vector256", "Int64", "1", "32", "(long)8", "result[0] != 576460752303423488L", "(i == 2 ? result[i] != 576460752303423488L : result[i] != 0)"}), + ("ImmUnOpTest.template", new string[] { "Avx2", "Avx", "ShiftRightLogical128BitLane", "Vector256", "UInt64", "Vector256", "UInt64", "1", "32", "(ulong)8", "result[0] != 576460752303423488UL", "(i == 2 ? result[i] != 576460752303423488UL : result[i] != 0)"}), }; private static void ProcessInputs(string isa, (string templateFileName, string[] templateData)[] inputs) @@ -344,12 +438,22 @@ namespace JIT.HardwareIntrinsics.X86 } } +private static bool isImmTemplate(string name) +{ + return name == "ImmUnOpTest.template"; +} + private static void ProcessInput(StreamWriter testListFile, (string templateFileName, string[] templateData) input) { var testName = $"{input.templateData[2]}.{input.templateData[4]}"; + if (isImmTemplate(input.templateFileName)) + { + testName += $".{input.templateData[7]}"; + } + // Ex: ["Add.Single"] = AddSingle - testListFile.WriteLine($@" [""{testName}""] = {input.templateData[2]}{input.templateData[4]},"); + testListFile.WriteLine($@" [""{testName}""] = {input.templateData[2]}{input.templateData[4]}{(isImmTemplate(input.templateFileName) ? input.templateData[7] : "")},"); var testFileName = Path.Combine("..", input.templateData[0], $"{testName}.cs"); var template = File.ReadAllText(input.templateFileName); diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template new file mode 100644 index 0000000000..f63b40db2a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template @@ -0,0 +1,313 @@ +// 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 {2}{4}{7}() + {{ + var test = new SimpleUnaryOpTest__{2}{4}{7}(); + + if (test.IsSupported) + {{ + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({1}.IsSupported) + {{ + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + }} + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if ({1}.IsSupported) + {{ + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + }} + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if ({1}.IsSupported) + {{ + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + }} + + // 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 SimpleUnaryOpTest__{2}{4}{7} + {{ + private const int VectorSize = {8}; + + private const int Op1ElementCount = VectorSize / sizeof({6}); + private const int RetElementCount = VectorSize / sizeof({4}); + + private static {6}[] _data = new {6}[Op1ElementCount]; + + private static {5}<{6}> _clsVar; + + private {5}<{6}> _fld; + + private SimpleUnaryOpTest__DataTable<{4}, {6}> _dataTable; + + static SimpleUnaryOpTest__{2}{4}{7}() + {{ + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) {{ _data[i] = {9}; }} + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{5}<{6}>, byte>(ref _clsVar), ref Unsafe.As<{6}, byte>(ref _data[0]), VectorSize); + }} + + public SimpleUnaryOpTest__{2}{4}{7}() + {{ + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) {{ _data[i] = {9}; }} + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{5}<{6}>, byte>(ref _fld), ref Unsafe.As<{6}, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) {{ _data[i] = {9}; }} + _dataTable = new SimpleUnaryOpTest__DataTable<{4}, {6}>(_data, new {4}[RetElementCount], VectorSize); + }} + + public bool IsSupported => {0}.IsSupported; + + public bool Succeeded {{ get; set; }} + + public void RunBasicScenario_UnsafeRead() + {{ + var result = {0}.{2}( + Unsafe.Read<{5}<{6}>>(_dataTable.inArrayPtr), + {7} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunBasicScenario_Load() + {{ + var result = {0}.{2}( + {1}.Load{5}(({6}*)(_dataTable.inArrayPtr)), + {7} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunBasicScenario_LoadAligned() + {{ + var result = {0}.{2}( + {1}.LoadAligned{5}(({6}*)(_dataTable.inArrayPtr)), + {7} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunReflectionScenario_UnsafeRead() + {{ + var result = typeof({0}).GetMethod(nameof({0}.{2}), new Type[] {{ typeof({5}<{6}>), typeof(byte) }}) + .Invoke(null, new object[] {{ + Unsafe.Read<{5}<{6}>>(_dataTable.inArrayPtr), + (byte){7} + }}); + + Unsafe.Write(_dataTable.outArrayPtr, ({3}<{4}>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunReflectionScenario_Load() + {{ + var result = typeof({0}).GetMethod(nameof({0}.{2}), new Type[] {{ typeof({5}<{6}>), typeof(byte) }}) + .Invoke(null, new object[] {{ + {1}.Load{5}(({6}*)(_dataTable.inArrayPtr)), + (byte){7} + }}); + + Unsafe.Write(_dataTable.outArrayPtr, ({3}<{4}>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunReflectionScenario_LoadAligned() + {{ + var result = typeof({0}).GetMethod(nameof({0}.{2}), new Type[] {{ typeof({5}<{6}>), typeof(byte) }}) + .Invoke(null, new object[] {{ + {1}.LoadAligned{5}(({6}*)(_dataTable.inArrayPtr)), + (byte){7} + }}); + + Unsafe.Write(_dataTable.outArrayPtr, ({3}<{4}>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + }} + + public void RunClsVarScenario() + {{ + var result = {0}.{2}( + _clsVar, + {7} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + }} + + public void RunLclVarScenario_UnsafeRead() + {{ + var firstOp = Unsafe.Read<{5}<{6}>>(_dataTable.inArrayPtr); + var result = {0}.{2}(firstOp, {7}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + }} + + public void RunLclVarScenario_Load() + {{ + var firstOp = {1}.Load{5}(({6}*)(_dataTable.inArrayPtr)); + var result = {0}.{2}(firstOp, {7}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + }} + + public void RunLclVarScenario_LoadAligned() + {{ + var firstOp = {1}.LoadAligned{5}(({6}*)(_dataTable.inArrayPtr)); + var result = {0}.{2}(firstOp, {7}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + }} + + public void RunLclFldScenario() + {{ + var test = new SimpleUnaryOpTest__{2}{4}{7}(); + var result = {0}.{2}(test._fld, {7}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + }} + + public void RunFldScenario() + {{ + var result = {0}.{2}(_fld, {7}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + }} + + public void RunUnsupportedScenario() + {{ + Succeeded = false; + + try + {{ + RunBasicScenario_UnsafeRead(); + }} + catch (PlatformNotSupportedException) + {{ + Succeeded = true; + }} + }} + + private void ValidateResult({5}<{6}> firstOp, void* result, [CallerMemberName] string method = "") + {{ + {6}[] inArray = new {6}[Op1ElementCount]; + {4}[] outArray = new {4}[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{4}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + }} + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + {{ + {6}[] inArray = new {6}[Op1ElementCount]; + {4}[] outArray = new {4}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{6}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{4}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + }} + + private void ValidateResult({6}[] firstOp, {4}[] result, [CallerMemberName] string method = "") + {{ + if ({10}) + {{ + Succeeded = false; + }} + else + {{ + for (var i = 1; i < RetElementCount; i++) + {{ + if ({11}) + {{ + Succeeded = false; + break; + }} + }} + }} + + if (!Succeeded) + {{ + Console.WriteLine($"{{nameof({0})}}.{{nameof({0}.{2})}}<{4}>({5}<{6}><9>): {{method}} failed:"); + Console.WriteLine($" firstOp: ({{string.Join(", ", firstOp)}})"); + Console.WriteLine($" result: ({{string.Join(", ", result)}})"); + Console.WriteLine(); + }} + }} + }} +}} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs index 768e3adf08..bbb1468b25 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs @@ -98,6 +98,50 @@ namespace JIT.HardwareIntrinsics.X86 ["Xor.UInt16"] = XorUInt16, ["Xor.UInt32"] = XorUInt32, ["Xor.UInt64"] = XorUInt64, + ["ShiftLeftLogical.Int16.1"] = ShiftLeftLogicalInt161, + ["ShiftLeftLogical.UInt16.1"] = ShiftLeftLogicalUInt161, + ["ShiftLeftLogical.Int32.1"] = ShiftLeftLogicalInt321, + ["ShiftLeftLogical.UInt32.1"] = ShiftLeftLogicalUInt321, + ["ShiftLeftLogical.Int64.1"] = ShiftLeftLogicalInt641, + ["ShiftLeftLogical.UInt64.1"] = ShiftLeftLogicalUInt641, + ["ShiftLeftLogical.Int16.16"] = ShiftLeftLogicalInt1616, + ["ShiftLeftLogical.UInt16.16"] = ShiftLeftLogicalUInt1616, + ["ShiftLeftLogical.Int32.32"] = ShiftLeftLogicalInt3232, + ["ShiftLeftLogical.UInt32.32"] = ShiftLeftLogicalUInt3232, + ["ShiftLeftLogical.Int64.64"] = ShiftLeftLogicalInt6464, + ["ShiftLeftLogical.UInt64.64"] = ShiftLeftLogicalUInt6464, + ["ShiftRightLogical.Int16.1"] = ShiftRightLogicalInt161, + ["ShiftRightLogical.UInt16.1"] = ShiftRightLogicalUInt161, + ["ShiftRightLogical.Int32.1"] = ShiftRightLogicalInt321, + ["ShiftRightLogical.UInt32.1"] = ShiftRightLogicalUInt321, + ["ShiftRightLogical.Int64.1"] = ShiftRightLogicalInt641, + ["ShiftRightLogical.UInt64.1"] = ShiftRightLogicalUInt641, + ["ShiftRightLogical.Int16.16"] = ShiftRightLogicalInt1616, + ["ShiftRightLogical.UInt16.16"] = ShiftRightLogicalUInt1616, + ["ShiftRightLogical.Int32.32"] = ShiftRightLogicalInt3232, + ["ShiftRightLogical.UInt32.32"] = ShiftRightLogicalUInt3232, + ["ShiftRightLogical.Int64.64"] = ShiftRightLogicalInt6464, + ["ShiftRightLogical.UInt64.64"] = ShiftRightLogicalUInt6464, + ["ShiftRightArithmetic.Int16.1"] = ShiftRightArithmeticInt161, + ["ShiftRightArithmetic.Int32.1"] = ShiftRightArithmeticInt321, + ["ShiftRightArithmetic.Int16.16"] = ShiftRightArithmeticInt1616, + ["ShiftRightArithmetic.Int32.32"] = ShiftRightArithmeticInt3232, + ["ShiftLeftLogical128BitLane.SByte.1"] = ShiftLeftLogical128BitLaneSByte1, + ["ShiftLeftLogical128BitLane.Byte.1"] = ShiftLeftLogical128BitLaneByte1, + ["ShiftLeftLogical128BitLane.Int16.1"] = ShiftLeftLogical128BitLaneInt161, + ["ShiftLeftLogical128BitLane.UInt16.1"] = ShiftLeftLogical128BitLaneUInt161, + ["ShiftLeftLogical128BitLane.Int32.1"] = ShiftLeftLogical128BitLaneInt321, + ["ShiftLeftLogical128BitLane.UInt32.1"] = ShiftLeftLogical128BitLaneUInt321, + ["ShiftLeftLogical128BitLane.Int64.1"] = ShiftLeftLogical128BitLaneInt641, + ["ShiftLeftLogical128BitLane.UInt64.1"] = ShiftLeftLogical128BitLaneUInt641, + ["ShiftRightLogical128BitLane.SByte.1"] = ShiftRightLogical128BitLaneSByte1, + ["ShiftRightLogical128BitLane.Byte.1"] = ShiftRightLogical128BitLaneByte1, + ["ShiftRightLogical128BitLane.Int16.1"] = ShiftRightLogical128BitLaneInt161, + ["ShiftRightLogical128BitLane.UInt16.1"] = ShiftRightLogical128BitLaneUInt161, + ["ShiftRightLogical128BitLane.Int32.1"] = ShiftRightLogical128BitLaneInt321, + ["ShiftRightLogical128BitLane.UInt32.1"] = ShiftRightLogical128BitLaneUInt321, + ["ShiftRightLogical128BitLane.Int64.1"] = ShiftRightLogical128BitLaneInt641, + ["ShiftRightLogical128BitLane.UInt64.1"] = ShiftRightLogical128BitLaneUInt641, }; } } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.1.cs new file mode 100644 index 0000000000..923650f35d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt161(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.16.cs new file mode 100644 index 0000000000..4247066bb8 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt1616() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt1616 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt1616(); + var result = Sse2.ShiftLeftLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.1.cs new file mode 100644 index 0000000000..cb889f0db8 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt321(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.32.cs new file mode 100644 index 0000000000..33b2d587c3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt3232() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt3232 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt3232(); + var result = Sse2.ShiftLeftLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.1.cs new file mode 100644 index 0000000000..0f9b881608 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt641(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if ((long)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((long)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.64.cs new file mode 100644 index 0000000000..35bb98c15b --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.Int64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalInt6464() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalInt6464 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalInt6464(); + var result = Sse2.ShiftLeftLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.1.cs new file mode 100644 index 0000000000..54345fcbb7 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt161(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if ((ushort)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ushort)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.16.cs new file mode 100644 index 0000000000..d8afd389ab --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt1616() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt1616 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt1616(); + var result = Sse2.ShiftLeftLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.1.cs new file mode 100644 index 0000000000..8ce9abf18e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt321(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if ((uint)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((uint)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.32.cs new file mode 100644 index 0000000000..14ae467c02 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt3232() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt3232 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt3232(); + var result = Sse2.ShiftLeftLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0!= result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.1.cs new file mode 100644 index 0000000000..96adcee208 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt641(); + var result = Sse2.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if ((ulong)(firstOp[0] << 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ulong)(firstOp[i] << 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.64.cs new file mode 100644 index 0000000000..f1c0d36018 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical.UInt64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogicalUInt6464() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogicalUInt6464 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogicalUInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogicalUInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogicalUInt6464(); + var result = Sse2.ShiftLeftLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Byte.1.cs new file mode 100644 index 0000000000..740d827e43 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Byte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneByte1() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Byte); + private const int RetElementCount = VectorSize / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128<Byte> _clsVar; + + private Vector128<Byte> _fld; + + private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneByte1(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Byte> firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 0) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 8) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<Byte>(Vector128<Byte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int16.1.cs new file mode 100644 index 0000000000..59e9baa436 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt161(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int32.1.cs new file mode 100644 index 0000000000..b97429190e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt321(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int64.1.cs new file mode 100644 index 0000000000..4c9e1f349c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneInt641(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.SByte.1.cs new file mode 100644 index 0000000000..7db3c44e83 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.SByte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneSByte1() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(SByte); + private const int RetElementCount = VectorSize / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128<SByte> _clsVar; + + private Vector128<SByte> _fld; + + private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneSByte1(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<SByte> firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 0) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 8) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<SByte>(Vector128<SByte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt16.1.cs new file mode 100644 index 0000000000..7262558556 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt161() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt161(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt32.1.cs new file mode 100644 index 0000000000..d9f8e932b5 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt321() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt321(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt64.1.cs new file mode 100644 index 0000000000..9bdb404d2f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftLeftLogical128BitLane.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftLeftLogical128BitLaneUInt641() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftLeftLogical128BitLane( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftLeftLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftLeftLogical128BitLaneUInt641(); + var result = Sse2.ShiftLeftLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftLeftLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 2048) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftLeftLogical128BitLane)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.1.cs new file mode 100644 index 0000000000..47b0e2cf67 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightArithmetic( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt161(); + var result = Sse2.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightArithmetic)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.16.cs new file mode 100644 index 0000000000..48e5524e67 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt1616 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightArithmetic( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightArithmetic( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt1616(); + var result = Sse2.ShiftRightArithmetic(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightArithmetic(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 15) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 15) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightArithmetic)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.1.cs new file mode 100644 index 0000000000..b6370ade18 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightArithmetic( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt321(); + var result = Sse2.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightArithmetic)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.32.cs new file mode 100644 index 0000000000..5a0fba1d77 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightArithmetic.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightArithmeticInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightArithmeticInt3232 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightArithmeticInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightArithmeticInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightArithmetic( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightArithmetic( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightArithmetic( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightArithmetic(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightArithmeticInt3232(); + var result = Sse2.ShiftRightArithmetic(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightArithmetic(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 31) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 31) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightArithmetic)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.1.cs new file mode 100644 index 0000000000..ef050e5474 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt161(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((short)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((short)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.16.cs new file mode 100644 index 0000000000..54b9dfe2a0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt1616 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt1616(); + var result = Sse2.ShiftRightLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.1.cs new file mode 100644 index 0000000000..a9c87d5cbd --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt321(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((int)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((int)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.32.cs new file mode 100644 index 0000000000..db62c8284a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt3232 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt3232(); + var result = Sse2.ShiftRightLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.1.cs new file mode 100644 index 0000000000..a307b6bc27 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt641(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if ((long)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((long)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.64.cs new file mode 100644 index 0000000000..ec3026ddbc --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.Int64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalInt6464() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalInt6464 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalInt6464(); + var result = Sse2.ShiftRightLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.1.cs new file mode 100644 index 0000000000..06f508f9e2 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt161(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if ((ushort)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ushort)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.16.cs new file mode 100644 index 0000000000..e275bc6830 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt16.16.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt1616() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt1616(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt1616 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt1616() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt1616() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt1616(); + var result = Sse2.ShiftRightLogical(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.1.cs new file mode 100644 index 0000000000..d33f3f5847 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt321(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if ((uint)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((uint)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.32.cs new file mode 100644 index 0000000000..35c4c106d3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt32.32.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt3232() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt3232(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt3232 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt3232() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt3232() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt3232(); + var result = Sse2.ShiftRightLogical(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0!= result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.1.cs new file mode 100644 index 0000000000..d9ded20263 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt641(); + var result = Sse2.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if ((ulong)(firstOp[0] >> 1) != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((ulong)(firstOp[i] >> 1) != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.64.cs new file mode 100644 index 0000000000..0665bf0eb0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical.UInt64.64.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogicalUInt6464() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt6464(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogicalUInt6464 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogicalUInt6464() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogicalUInt6464() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)64 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical( + _clsVar, + 64 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical(firstOp, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogicalUInt6464(); + var result = Sse2.ShiftRightLogical(test._fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical(_fld, 64); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (0 != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (0 != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Byte.1.cs new file mode 100644 index 0000000000..0887871211 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Byte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneByte1() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Byte); + private const int RetElementCount = VectorSize / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128<Byte> _clsVar; + + private Vector128<Byte> _fld; + + private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Byte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneByte1(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Byte> firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 8) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 15 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<Byte>(Vector128<Byte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int16.1.cs new file mode 100644 index 0000000000..fc3930bd01 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int16); + private const int RetElementCount = VectorSize / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128<Int16> _clsVar; + + private Vector128<Int16> _fld; + + private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt161(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 7 ? result[i] != 0 : result[i] != 2048)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<Int16>(Vector128<Int16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int32.1.cs new file mode 100644 index 0000000000..19cfbbd1b0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int32); + private const int RetElementCount = VectorSize / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128<Int32> _clsVar; + + private Vector128<Int32> _fld; + + private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt321(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 134217728) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 3 ? result[i] != 0 : result[i] != 134217728)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<Int32>(Vector128<Int32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int64.1.cs new file mode 100644 index 0000000000..c061f03364 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.Int64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(Int64); + private const int RetElementCount = VectorSize / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128<Int64> _clsVar; + + private Vector128<Int64> _fld; + + private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<Int64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneInt641(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 576460752303423488L) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((result[i] != 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<Int64>(Vector128<Int64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.SByte.1.cs new file mode 100644 index 0000000000..86d78e109f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.SByte.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneSByte1() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(SByte); + private const int RetElementCount = VectorSize / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128<SByte> _clsVar; + + private Vector128<SByte> _fld; + + private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<SByte>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneSByte1(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<SByte> firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + if (result[0] != 8) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 15 ? result[i] != 0 : result[i] != 8)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<SByte>(Vector128<SByte><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt16.1.cs new file mode 100644 index 0000000000..c8ed4495fa --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt16.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt161() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt16); + private const int RetElementCount = VectorSize / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128<UInt16> _clsVar; + + private Vector128<UInt16> _fld; + + private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt16>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt161(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if (result[0] != 2048) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 7 ? result[i] != 0 : result[i] != 2048)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<UInt16>(Vector128<UInt16><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt32.1.cs new file mode 100644 index 0000000000..60275e5534 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt32.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt321() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt32); + private const int RetElementCount = VectorSize / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128<UInt32> _clsVar; + + private Vector128<UInt32> _fld; + + private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt32>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt321(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if (result[0] != 134217728) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((i == 3 ? result[i] != 0 : result[i] != 134217728)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<UInt32>(Vector128<UInt32><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt64.1.cs new file mode 100644 index 0000000000..c667802dc9 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/ShiftRightLogical128BitLane.UInt64.1.cs @@ -0,0 +1,313 @@ +// 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 ShiftRightLogical128BitLaneUInt641() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Sse2.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // 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 SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641 + { + private const int VectorSize = 16; + + private const int Op1ElementCount = VectorSize / sizeof(UInt64); + private const int RetElementCount = VectorSize / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128<UInt64> _clsVar; + + private Vector128<UInt64> _fld; + + private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable; + + static SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + } + + public SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)8; } + _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize); + } + + public bool IsSupported => Sse2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Sse2.ShiftRightLogical128BitLane( + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Sse2.ShiftRightLogical128BitLane( + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), new Type[] { typeof(Vector128<UInt64>), typeof(byte) }) + .Invoke(null, new object[] { + Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Sse2.ShiftRightLogical128BitLane( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = Sse2.ShiftRightLogical128BitLane(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ShiftRightLogical128BitLaneUInt641(); + var result = Sse2.ShiftRightLogical128BitLane(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Sse2.ShiftRightLogical128BitLane(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if (result[0] != 576460752303423488UL) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((result[i] != 0)) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.ShiftRightLogical128BitLane)}<UInt64>(Vector128<UInt64><9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj index ecdfd970cd..d217e01700 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj @@ -95,6 +95,50 @@ <Compile Include="Or.UInt16.cs" /> <Compile Include="Or.UInt32.cs" /> <Compile Include="Or.UInt64.cs" /> + <Compile Include="ShiftLeftLogical.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.1.cs" /> + <Compile Include="ShiftLeftLogical.Int16.16.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.16.cs" /> + <Compile Include="ShiftLeftLogical.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.32.cs" /> + <Compile Include="ShiftLeftLogical.Int64.64.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightLogical.Int16.1.cs" /> + <Compile Include="ShiftRightLogical.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical.Int32.1.cs" /> + <Compile Include="ShiftRightLogical.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical.Int64.1.cs" /> + <Compile Include="ShiftRightLogical.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical.Int16.16.cs" /> + <Compile Include="ShiftRightLogical.UInt16.16.cs" /> + <Compile Include="ShiftRightLogical.Int32.32.cs" /> + <Compile Include="ShiftRightLogical.UInt32.32.cs" /> + <Compile Include="ShiftRightLogical.Int64.64.cs" /> + <Compile Include="ShiftRightLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.16.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt64.1.cs" /> <Compile Include="Subtract.Double.cs" /> <Compile Include="Subtract.Byte.cs" /> <Compile Include="Subtract.Int16.cs" /> @@ -116,6 +160,7 @@ <Compile Include="Program.Sse2.cs" /> <Compile Include="..\Shared\Program.cs" /> <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" /> + <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj index 2611d31617..ece9047856 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj @@ -95,6 +95,50 @@ <Compile Include="Or.UInt16.cs" /> <Compile Include="Or.UInt32.cs" /> <Compile Include="Or.UInt64.cs" /> + <Compile Include="ShiftLeftLogical.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.1.cs" /> + <Compile Include="ShiftLeftLogical.Int16.16.cs" /> + <Compile Include="ShiftLeftLogical.UInt16.16.cs" /> + <Compile Include="ShiftLeftLogical.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical.UInt32.32.cs" /> + <Compile Include="ShiftLeftLogical.Int64.64.cs" /> + <Compile Include="ShiftLeftLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightLogical.Int16.1.cs" /> + <Compile Include="ShiftRightLogical.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical.Int32.1.cs" /> + <Compile Include="ShiftRightLogical.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical.Int64.1.cs" /> + <Compile Include="ShiftRightLogical.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical.Int16.16.cs" /> + <Compile Include="ShiftRightLogical.UInt16.16.cs" /> + <Compile Include="ShiftRightLogical.Int32.32.cs" /> + <Compile Include="ShiftRightLogical.UInt32.32.cs" /> + <Compile Include="ShiftRightLogical.Int64.64.cs" /> + <Compile Include="ShiftRightLogical.UInt64.64.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.1.cs" /> + <Compile Include="ShiftRightArithmetic.Int16.16.cs" /> + <Compile Include="ShiftRightArithmetic.Int32.32.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftLeftLogical128BitLane.UInt64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.SByte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Byte.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt16.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt32.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.Int64.1.cs" /> + <Compile Include="ShiftRightLogical128BitLane.UInt64.1.cs" /> <Compile Include="Subtract.Double.cs" /> <Compile Include="Subtract.Byte.cs" /> <Compile Include="Subtract.Int16.cs" /> @@ -116,6 +160,7 @@ <Compile Include="Program.Sse2.cs" /> <Compile Include="..\Shared\Program.cs" /> <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" /> + <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> |