diff options
Diffstat (limited to 'tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs')
-rw-r--r-- | tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs new file mode 100644 index 0000000000..098f31040b --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs @@ -0,0 +1,430 @@ +// 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 BlendVariableInt32() + { + var test = new SimpleTernaryOpTest__BlendVariableInt32(); + + 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 class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 SimpleTernaryOpTest__BlendVariableInt32 + { + private struct TestStruct + { + public Vector256<Int32> _fld1; + public Vector256<Int32> _fld2; + public Vector256<Int32> _fld3; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleTernaryOpTest__BlendVariableInt32 testClass) + { + var result = Avx2.BlendVariable(_fld1, _fld2, _fld3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32); + private static readonly int Op3ElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + private static Int32[] _data3 = new Int32[Op3ElementCount]; + + private static Vector256<Int32> _clsVar1; + private static Vector256<Int32> _clsVar2; + private static Vector256<Int32> _clsVar3; + + private Vector256<Int32> _fld1; + private Vector256<Int32> _fld2; + private Vector256<Int32> _fld3; + + private SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32> _dataTable; + + static SimpleTernaryOpTest__BlendVariableInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + } + + public SimpleTernaryOpTest__BlendVariableInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); } + _dataTable = new SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32>(_data1, _data2, _data3, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx2.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Avx2.BlendVariable( + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr), + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr), + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray3Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Avx2.BlendVariable( + Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)), + Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr)), + Avx.LoadVector256((Int32*)(_dataTable.inArray3Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Avx2.BlendVariable( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)), + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr)), + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray3Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Avx2).GetMethod(nameof(Avx2.BlendVariable), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>), typeof(Vector256<Int32>) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr), + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr), + Unsafe.Read<Vector256<Int32>>(_dataTable.inArray3Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Avx2).GetMethod(nameof(Avx2.BlendVariable), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>), typeof(Vector256<Int32>) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)), + Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr)), + Avx.LoadVector256((Int32*)(_dataTable.inArray3Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Avx2).GetMethod(nameof(Avx2.BlendVariable), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>), typeof(Vector256<Int32>) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)), + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr)), + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray3Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Avx2.BlendVariable( + _clsVar1, + _clsVar2, + _clsVar3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr); + var thirdOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray3Ptr); + var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr)); + var thirdOp = Avx.LoadVector256((Int32*)(_dataTable.inArray3Ptr)); + var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr)); + var thirdOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray3Ptr)); + var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleTernaryOpTest__BlendVariableInt32(); + var result = Avx2.BlendVariable(test._fld1, test._fld2, test._fld3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Avx2.BlendVariable(_fld1, _fld2, _fld3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Avx2.BlendVariable(test._fld1, test._fld2, test._fld3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256<Int32> firstOp, Vector256<Int32> secondOp, Vector256<Int32> thirdOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] inArray3 = new Int32[Op3ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), thirdOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] inArray3 = new Int32[Op3ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] thirdOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((thirdOp[0] != 0) ? secondOp[0] != result[0] : firstOp[0] != result[0]) + { + Succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ((thirdOp[i] != 0) ? secondOp[i] != result[i] : firstOp[i] != result[i]) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<Int32>(Vector256<Int32>, Vector256<Int32>, Vector256<Int32>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + } +} |