// 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 BlendVariableUInt32() { var test = new SimpleTernaryOpTest__BlendVariableUInt32(); 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__BlendVariableUInt32 { private struct TestStruct { public Vector256 _fld1; public Vector256 _fld2; public Vector256 _fld3; public static TestStruct Create() { var testStruct = new TestStruct(); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); return testStruct; } public void RunStructFldScenario(SimpleTernaryOpTest__BlendVariableUInt32 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>() / sizeof(UInt32); private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int Op3ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static UInt32[] _data1 = new UInt32[Op1ElementCount]; private static UInt32[] _data2 = new UInt32[Op2ElementCount]; private static UInt32[] _data3 = new UInt32[Op3ElementCount]; private static Vector256 _clsVar1; private static Vector256 _clsVar2; private static Vector256 _clsVar3; private Vector256 _fld1; private Vector256 _fld2; private Vector256 _fld3; private SimpleTernaryOpTest__DataTable _dataTable; static SimpleTernaryOpTest__BlendVariableUInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } public SimpleTernaryOpTest__BlendVariableUInt32() { Succeeded = true; for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); } _dataTable = new SimpleTernaryOpTest__DataTable(_data1, _data2, _data3, new UInt32[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>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_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((UInt32*)(_dataTable.inArray1Ptr)), Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr)), Avx.LoadVector256((UInt32*)(_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((UInt32*)(_dataTable.inArray1Ptr)), Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr)), Avx.LoadAlignedVector256((UInt32*)(_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), typeof(Vector256), typeof(Vector256) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) }); Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(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), typeof(Vector256), typeof(Vector256) }) .Invoke(null, new object[] { Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)), Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr)), Avx.LoadVector256((UInt32*)(_dataTable.inArray3Ptr)) }); Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(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), typeof(Vector256), typeof(Vector256) }) .Invoke(null, new object[] { Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)), Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr)), Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray3Ptr)) }); Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(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>(_dataTable.inArray1Ptr); var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); var thirdOp = Unsafe.Read>(_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((UInt32*)(_dataTable.inArray1Ptr)); var secondOp = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr)); var thirdOp = Avx.LoadVector256((UInt32*)(_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((UInt32*)(_dataTable.inArray1Ptr)); var secondOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr)); var thirdOp = Avx.LoadAlignedVector256((UInt32*)(_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__BlendVariableUInt32(); 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 firstOp, Vector256 secondOp, Vector256 thirdOp, void* result, [CallerMemberName] string method = "") { UInt32[] inArray1 = new UInt32[Op1ElementCount]; UInt32[] inArray2 = new UInt32[Op2ElementCount]; UInt32[] inArray3 = new UInt32[Op3ElementCount]; UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray3[0]), thirdOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); } private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "") { UInt32[] inArray1 = new UInt32[Op1ElementCount]; UInt32[] inArray2 = new UInt32[Op2ElementCount]; UInt32[] inArray3 = new UInt32[Op3ElementCount]; UInt32[] outArray = new UInt32[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray3[0]), ref Unsafe.AsRef(thirdOp), (uint)Unsafe.SizeOf>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); } private void ValidateResult(UInt32[] firstOp, UInt32[] secondOp, UInt32[] thirdOp, UInt32[] 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)}(Vector256, Vector256, Vector256): {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); } } } }