Updating the Avx2.Add HardwareIntrinsic tests to be generated from a template.
authorTanner Gooding <tagoo@outlook.com>
Sat, 27 Jan 2018 23:30:36 +0000 (15:30 -0800)
committerTanner Gooding <tagoo@outlook.com>
Sun, 28 Jan 2018 01:56:39 +0000 (17:56 -0800)
12 files changed:
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add_r.csproj with 79% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj [moved from tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add_ro.csproj with 79% similarity]
tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx

diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs
new file mode 100644 (file)
index 0000000..4844728
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddByte()
+        {
+            var test = new SimpleBinaryOpTest__AddByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddByte
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(Byte);
+
+        private static Byte[] _data1 = new Byte[ElementCount];
+        private static Byte[] _data2 = new Byte[ElementCount];
+
+        private static Vector256<Byte> _clsVar1;
+        private static Vector256<Byte> _clsVar2;
+
+        private Vector256<Byte> _fld1;
+        private Vector256<Byte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+        static SimpleBinaryOpTest__AddByte()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddByte()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddByte();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            Byte[] inArray1 = new Byte[ElementCount];
+            Byte[] inArray2 = new Byte[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            if ((byte)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((byte)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Byte>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs
new file mode 100644 (file)
index 0000000..7123852
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddInt16()
+        {
+            var test = new SimpleBinaryOpTest__AddInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddInt16
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(Int16);
+
+        private static Int16[] _data1 = new Int16[ElementCount];
+        private static Int16[] _data2 = new Int16[ElementCount];
+
+        private static Vector256<Int16> _clsVar1;
+        private static Vector256<Int16> _clsVar2;
+
+        private Vector256<Int16> _fld1;
+        private Vector256<Int16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+        static SimpleBinaryOpTest__AddInt16()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddInt16()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddInt16();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, Int16[] result, [CallerMemberName] string method = "")
+        {
+            Int16[] inArray1 = new Int16[ElementCount];
+            Int16[] inArray2 = new Int16[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+        {
+            if ((short)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((short)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int16>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs
new file mode 100644 (file)
index 0000000..2b1248e
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddInt32()
+        {
+            var test = new SimpleBinaryOpTest__AddInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddInt32
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(Int32);
+
+        private static Int32[] _data1 = new Int32[ElementCount];
+        private static Int32[] _data2 = new Int32[ElementCount];
+
+        private static Vector256<Int32> _clsVar1;
+        private static Vector256<Int32> _clsVar2;
+
+        private Vector256<Int32> _fld1;
+        private Vector256<Int32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+        static SimpleBinaryOpTest__AddInt32()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddInt32()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddInt32();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, Int32[] result, [CallerMemberName] string method = "")
+        {
+            Int32[] inArray1 = new Int32[ElementCount];
+            Int32[] inArray2 = new Int32[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+        {
+            if ((int)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((int)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int32>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs
new file mode 100644 (file)
index 0000000..828c4c9
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddInt64()
+        {
+            var test = new SimpleBinaryOpTest__AddInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddInt64
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(Int64);
+
+        private static Int64[] _data1 = new Int64[ElementCount];
+        private static Int64[] _data2 = new Int64[ElementCount];
+
+        private static Vector256<Int64> _clsVar1;
+        private static Vector256<Int64> _clsVar2;
+
+        private Vector256<Int64> _fld1;
+        private Vector256<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+        static SimpleBinaryOpTest__AddInt64()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddInt64()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddInt64();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, Int64[] result, [CallerMemberName] string method = "")
+        {
+            Int64[] inArray1 = new Int64[ElementCount];
+            Int64[] inArray2 = new Int64[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+        {
+            if ((long)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((long)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int64>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs
new file mode 100644 (file)
index 0000000..e3ffcc0
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddSByte()
+        {
+            var test = new SimpleBinaryOpTest__AddSByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddSByte
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(SByte);
+
+        private static SByte[] _data1 = new SByte[ElementCount];
+        private static SByte[] _data2 = new SByte[ElementCount];
+
+        private static Vector256<SByte> _clsVar1;
+        private static Vector256<SByte> _clsVar2;
+
+        private Vector256<SByte> _fld1;
+        private Vector256<SByte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+        static SimpleBinaryOpTest__AddSByte()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddSByte()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddSByte();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, SByte[] result, [CallerMemberName] string method = "")
+        {
+            SByte[] inArray1 = new SByte[ElementCount];
+            SByte[] inArray2 = new SByte[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+        {
+            if ((sbyte)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((sbyte)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<SByte>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs
new file mode 100644 (file)
index 0000000..ec71b11
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddUInt16()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddUInt16
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(UInt16);
+
+        private static UInt16[] _data1 = new UInt16[ElementCount];
+        private static UInt16[] _data2 = new UInt16[ElementCount];
+
+        private static Vector256<UInt16> _clsVar1;
+        private static Vector256<UInt16> _clsVar2;
+
+        private Vector256<UInt16> _fld1;
+        private Vector256<UInt16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+        static SimpleBinaryOpTest__AddUInt16()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddUInt16()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt16();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, UInt16[] result, [CallerMemberName] string method = "")
+        {
+            UInt16[] inArray1 = new UInt16[ElementCount];
+            UInt16[] inArray2 = new UInt16[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+        {
+            if ((ushort)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((ushort)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt16>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs
new file mode 100644 (file)
index 0000000..6b52988
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddUInt32()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddUInt32
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(UInt32);
+
+        private static UInt32[] _data1 = new UInt32[ElementCount];
+        private static UInt32[] _data2 = new UInt32[ElementCount];
+
+        private static Vector256<UInt32> _clsVar1;
+        private static Vector256<UInt32> _clsVar2;
+
+        private Vector256<UInt32> _fld1;
+        private Vector256<UInt32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+        static SimpleBinaryOpTest__AddUInt32()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddUInt32()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt32();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, UInt32[] result, [CallerMemberName] string method = "")
+        {
+            UInt32[] inArray1 = new UInt32[ElementCount];
+            UInt32[] inArray2 = new UInt32[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+        {
+            if ((uint)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((uint)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt32>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs
new file mode 100644 (file)
index 0000000..6ddab32
--- /dev/null
@@ -0,0 +1,209 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        private static void AddUInt64()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works
+                test.RunBasicScenario();
+
+                // Validates calling via reflection works
+                test.RunReflectionScenario();
+
+                // Validates passing a static member works
+                test.RunClsVarScenario();
+
+                // Validates passing a local works
+                test.RunLclVarScenario();
+
+                // Validates passing the field of a local works
+                test.RunLclFldScenario();
+
+                // Validates passing an instance member works
+                test.RunFldScenario();
+            }
+            else
+            {
+                // Validates we throw on unsupported hardware
+                test.RunUnsupportedScenario();
+            }
+
+            if (!test.Succeeded)
+            {
+                throw new Exception("One or more scenarios did not complete as expected.");
+            }
+        }
+    }
+
+    public sealed unsafe class SimpleBinaryOpTest__AddUInt64
+    {
+        private const int VectorSize = 32;
+        private const int ElementCount = VectorSize / sizeof(UInt64);
+
+        private static UInt64[] _data1 = new UInt64[ElementCount];
+        private static UInt64[] _data2 = new UInt64[ElementCount];
+
+        private static Vector256<UInt64> _clsVar1;
+        private static Vector256<UInt64> _clsVar2;
+
+        private Vector256<UInt64> _fld1;
+        private Vector256<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+        static SimpleBinaryOpTest__AddUInt64()
+        {
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+        }
+
+        public SimpleBinaryOpTest__AddUInt64()
+        {
+            Succeeded = true;
+
+            var random = new Random();
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+            for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount]);
+        }
+
+        public bool IsSupported => Avx2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario()
+        {
+            var result = Avx2.Add(
+                Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunReflectionScenario()
+        {
+            var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+            ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+        }
+
+        public void RunClsVarScenario()
+        {
+            var result = Avx2.Add(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+        }
+
+        public void RunLclVarScenario()
+        {
+            var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+            var result = Avx2.Add(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArray);
+        }
+
+        public void RunLclFldScenario()
+        {
+            var test = new SimpleBinaryOpTest__AddUInt64();
+            var result = Avx2.Add(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+        }
+
+        public void RunFldScenario()
+        {
+            var result = Avx2.Add(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArray);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            Succeeded = false;
+
+            try
+            {
+                RunBasicScenario();
+            }
+            catch (PlatformNotSupportedException)
+            {
+                Succeeded = true;
+            }
+        }
+
+        private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, UInt64[] result, [CallerMemberName] string method = "")
+        {
+            UInt64[] inArray1 = new UInt64[ElementCount];
+            UInt64[] inArray2 = new UInt64[ElementCount];
+
+            Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+            Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+            ValidateResult(inArray1, inArray2, result, method);
+        }
+
+        private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+        {
+            if ((ulong)(left[0] + right[0]) != result[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < left.Length; i++)
+                {
+                    if ((ulong)(left[i] + right[i]) != result[i])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt64>: {method} failed:");
+                Console.WriteLine($"    left: ({string.Join(", ", left)})");
+                Console.WriteLine($"   right: ({string.Join(", ", right)})");
+                Console.WriteLine($"  result: ({string.Join(", ", result)})");
+                Console.WriteLine();
+            }
+        }
+    }
+}
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Add.cs" />
+    <Compile Include="Add.Byte.cs" />
+    <Compile Include="Add.Int16.cs" />
+    <Compile Include="Add.Int32.cs" />
+    <Compile Include="Add.Int64.cs" />
+    <Compile Include="Add.SByte.cs" />
+    <Compile Include="Add.UInt16.cs" />
+    <Compile Include="Add.UInt32.cs" />
+    <Compile Include="Add.UInt64.cs" />
+    <Compile Include="Program.Avx2.cs" />
+    <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
   </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
   <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Add.cs" />
+    <Compile Include="Add.Byte.cs" />
+    <Compile Include="Add.Int16.cs" />
+    <Compile Include="Add.Int32.cs" />
+    <Compile Include="Add.Int64.cs" />
+    <Compile Include="Add.SByte.cs" />
+    <Compile Include="Add.UInt16.cs" />
+    <Compile Include="Add.UInt32.cs" />
+    <Compile Include="Add.UInt64.cs" />
+    <Compile Include="Program.Avx2.cs" />
+    <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\SimpleBinOpTest_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
new file mode 100644 (file)
index 0000000..c80c22b
--- /dev/null
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+    public static partial class Program
+    {
+        static Program()
+        {
+            TestList = new Dictionary<string, Action>() {
+                ["Add.Byte"] = AddByte,
+                ["Add.Int16"] = AddInt16,
+                ["Add.Int32"] = AddInt32,
+                ["Add.Int64"] = AddInt64,
+                ["Add.SByte"] = AddSByte,
+                ["Add.UInt16"] = AddUInt16,
+                ["Add.UInt32"] = AddUInt32,
+                ["Add.UInt64"] = AddUInt64,
+            };
+        }
+    }
+}
index ab60f27..58a1f37 100644 (file)
@@ -31,6 +31,19 @@ private static readonly (string templateFileName, string[] templateData)[] AvxIn
     ("SimpleBinOpTest.template", new string[] { "Avx", "Multiply", "Single", "Vector256", "32",       "(float)(random.NextDouble())",  "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] * right[i]) != BitConverter.SingleToInt32Bits(result[i])"}),
 };
 
+private static readonly (string templateFileName, string[] templateData)[] Avx2Inputs = new []
+{
+    // TemplateName                             Isa,    Method, BaseType, VectorType,  VectorSize, NextValue,                                              ValidateFirstResult,                         ValidateRemainingResults
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "Byte",   "Vector256", "32",       "(byte)(random.Next(0, byte.MaxValue))",                "(byte)(left[0] + right[0]) != result[0]",   "(byte)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "Int16",  "Vector256", "32",       "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] + right[0]) != result[0]",  "(short)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "Int32",  "Vector256", "32",       "(int)(random.Next(int.MinValue, int.MaxValue))",       "(int)(left[0] + right[0]) != result[0]",    "(int)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "Int64",  "Vector256", "32",       "(long)(random.Next(int.MinValue, int.MaxValue))",      "(long)(left[0] + right[0]) != result[0]",   "(long)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "SByte",  "Vector256", "32",       "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] + right[0]) != result[0]",  "(sbyte)(left[i] + right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template", new string[] { "Avx2", "Add",  "UInt16", "Vector256", "32",       "(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", "Add",  "UInt32", "Vector256", "32",       "(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", "Add",  "UInt64", "Vector256", "32",       "(ulong)(random.Next(0, int.MaxValue))",                "(ulong)(left[0] + right[0]) != result[0]",  "(ulong)(left[i] + right[i]) != result[i]"}),
+};
+
 private static void ProcessInputs(string isa, (string templateFileName, string[] templateData)[] inputs)
 {
     var testListFileName = Path.Combine("..", isa, $"Program.{isa}.cs");
@@ -84,3 +97,4 @@ private static void ProcessInput(StreamWriter testListFile, (string templateFile
 
 ProcessInputs("Sse2", Sse2Inputs);
 ProcessInputs("Avx", AvxInputs);
+ProcessInputs("Avx2", Avx2Inputs);