Updating the Avx2.Add HardwareIntrinsic tests to be generated from a template.
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx2 / Add.Int64.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System;
6 using System.Runtime.CompilerServices;
7 using System.Runtime.InteropServices;
8 using System.Runtime.Intrinsics;
9 using System.Runtime.Intrinsics.X86;
10
11 namespace JIT.HardwareIntrinsics.X86
12 {
13     public static partial class Program
14     {
15         private static void AddInt64()
16         {
17             var test = new SimpleBinaryOpTest__AddInt64();
18
19             if (test.IsSupported)
20             {
21                 // Validates basic functionality works
22                 test.RunBasicScenario();
23
24                 // Validates calling via reflection works
25                 test.RunReflectionScenario();
26
27                 // Validates passing a static member works
28                 test.RunClsVarScenario();
29
30                 // Validates passing a local works
31                 test.RunLclVarScenario();
32
33                 // Validates passing the field of a local works
34                 test.RunLclFldScenario();
35
36                 // Validates passing an instance member works
37                 test.RunFldScenario();
38             }
39             else
40             {
41                 // Validates we throw on unsupported hardware
42                 test.RunUnsupportedScenario();
43             }
44
45             if (!test.Succeeded)
46             {
47                 throw new Exception("One or more scenarios did not complete as expected.");
48             }
49         }
50     }
51
52     public sealed unsafe class SimpleBinaryOpTest__AddInt64
53     {
54         private const int VectorSize = 32;
55         private const int ElementCount = VectorSize / sizeof(Int64);
56
57         private static Int64[] _data1 = new Int64[ElementCount];
58         private static Int64[] _data2 = new Int64[ElementCount];
59
60         private static Vector256<Int64> _clsVar1;
61         private static Vector256<Int64> _clsVar2;
62
63         private Vector256<Int64> _fld1;
64         private Vector256<Int64> _fld2;
65
66         private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
67
68         static SimpleBinaryOpTest__AddInt64()
69         {
70             var random = new Random();
71
72             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)); }
73             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
74             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
75         }
76
77         public SimpleBinaryOpTest__AddInt64()
78         {
79             Succeeded = true;
80
81             var random = new Random();
82
83             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)); }
84             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
85             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
86
87             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)); }
88             _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount]);
89         }
90
91         public bool IsSupported => Avx2.IsSupported;
92
93         public bool Succeeded { get; set; }
94
95         public void RunBasicScenario()
96         {
97             var result = Avx2.Add(
98                 Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
99                 Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
100             );
101
102             Unsafe.Write(_dataTable.outArrayPtr, result);
103             ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
104         }
105
106         public void RunReflectionScenario()
107         {
108             var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
109                                      .Invoke(null, new object[] {
110                                         Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
111                                         Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
112                                      });
113
114             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
115             ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
116         }
117
118         public void RunClsVarScenario()
119         {
120             var result = Avx2.Add(
121                 _clsVar1,
122                 _clsVar2
123             );
124
125             Unsafe.Write(_dataTable.outArrayPtr, result);
126             ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
127         }
128
129         public void RunLclVarScenario()
130         {
131             var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
132             var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
133             var result = Avx2.Add(left, right);
134
135             Unsafe.Write(_dataTable.outArrayPtr, result);
136             ValidateResult(left, right, _dataTable.outArray);
137         }
138
139         public void RunLclFldScenario()
140         {
141             var test = new SimpleBinaryOpTest__AddInt64();
142             var result = Avx2.Add(test._fld1, test._fld2);
143
144             Unsafe.Write(_dataTable.outArrayPtr, result);
145             ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
146         }
147
148         public void RunFldScenario()
149         {
150             var result = Avx2.Add(_fld1, _fld2);
151
152             Unsafe.Write(_dataTable.outArrayPtr, result);
153             ValidateResult(_fld1, _fld2, _dataTable.outArray);
154         }
155
156         public void RunUnsupportedScenario()
157         {
158             Succeeded = false;
159
160             try
161             {
162                 RunBasicScenario();
163             }
164             catch (PlatformNotSupportedException)
165             {
166                 Succeeded = true;
167             }
168         }
169
170         private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, Int64[] result, [CallerMemberName] string method = "")
171         {
172             Int64[] inArray1 = new Int64[ElementCount];
173             Int64[] inArray2 = new Int64[ElementCount];
174
175             Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
176             Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
177
178             ValidateResult(inArray1, inArray2, result, method);
179         }
180
181         private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
182         {
183             if ((long)(left[0] + right[0]) != result[0])
184             {
185                 Succeeded = false;
186             }
187             else
188             {
189                 for (var i = 1; i < left.Length; i++)
190                 {
191                     if ((long)(left[i] + right[i]) != result[i])
192                     {
193                         Succeeded = false;
194                         break;
195                     }
196                 }
197             }
198
199             if (!Succeeded)
200             {
201                 Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int64>: {method} failed:");
202                 Console.WriteLine($"    left: ({string.Join(", ", left)})");
203                 Console.WriteLine($"   right: ({string.Join(", ", right)})");
204                 Console.WriteLine($"  result: ({string.Join(", ", result)})");
205                 Console.WriteLine();
206             }
207         }
208     }
209 }