Merge pull request #18504 from mikedn/comp-small
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx2 / InsertVector128.Int32.1.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 /******************************************************************************
6  * This file is auto-generated from a template file by the GenerateTests.csx  *
7  * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make    *
8  * changes, please update the corresponding template and run according to the *
9  * directions listed in the file.                                             *
10  ******************************************************************************/
11
12 using System;
13 using System.Runtime.CompilerServices;
14 using System.Runtime.InteropServices;
15 using System.Runtime.Intrinsics;
16 using System.Runtime.Intrinsics.X86;
17 using static System.Runtime.Intrinsics.X86.Sse;
18 using static System.Runtime.Intrinsics.X86.Sse2;
19
20 namespace JIT.HardwareIntrinsics.X86
21 {
22     public static partial class Program
23     {
24         private static void InsertVector128Int321()
25         {
26             var test = new SimpleBinaryOpTest__InsertVector128Int321();
27
28             if (test.IsSupported)
29             {
30                 // Validates basic functionality works, using Unsafe.Read
31                 test.RunBasicScenario_UnsafeRead();
32
33                 if (Avx.IsSupported)
34                 {
35                     // Validates basic functionality works, using Load
36                     test.RunBasicScenario_Load();
37
38                     // Validates basic functionality works, using LoadAligned
39                     test.RunBasicScenario_LoadAligned();
40                 }
41
42                 // Validates calling via reflection works, using Unsafe.Read
43                 test.RunReflectionScenario_UnsafeRead();
44
45                 if (Avx.IsSupported)
46                 {
47                     // Validates calling via reflection works, using Load
48                     test.RunReflectionScenario_Load();
49
50                     // Validates calling via reflection works, using LoadAligned
51                     test.RunReflectionScenario_LoadAligned();
52                 }
53
54                 // Validates passing a static member works
55                 test.RunClsVarScenario();
56
57                 // Validates passing a local works, using Unsafe.Read
58                 test.RunLclVarScenario_UnsafeRead();
59
60                 if (Avx.IsSupported)
61                 {
62                     // Validates passing a local works, using Load
63                     test.RunLclVarScenario_Load();
64
65                     // Validates passing a local works, using LoadAligned
66                     test.RunLclVarScenario_LoadAligned();
67                 }
68
69                 // Validates passing the field of a local works
70                 test.RunLclFldScenario();
71
72                 // Validates passing an instance member works
73                 test.RunFldScenario();
74             }
75             else
76             {
77                 // Validates we throw on unsupported hardware
78                 test.RunUnsupportedScenario();
79             }
80
81             if (!test.Succeeded)
82             {
83                 throw new Exception("One or more scenarios did not complete as expected.");
84             }
85         }
86     }
87
88     public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int321
89     {
90         private static readonly int LargestVectorSize = 32;
91
92         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32);
93         private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
94         private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32);
95
96         private static Int32[] _data1 = new Int32[Op1ElementCount];
97         private static Int32[] _data2 = new Int32[Op2ElementCount];
98
99         private static Vector256<Int32> _clsVar1;
100         private static Vector128<Int32> _clsVar2;
101
102         private Vector256<Int32> _fld1;
103         private Vector128<Int32> _fld2;
104
105         private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
106
107         static SimpleBinaryOpTest__InsertVector128Int321()
108         {
109             var random = new Random();
110
111             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
112             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
113             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
114             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
115         }
116
117         public SimpleBinaryOpTest__InsertVector128Int321()
118         {
119             Succeeded = true;
120
121             var random = new Random();
122
123             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
124             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
125             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
126             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
127
128             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
129             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
130             _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
131         }
132
133         public bool IsSupported => Avx2.IsSupported;
134
135         public bool Succeeded { get; set; }
136
137         public void RunBasicScenario_UnsafeRead()
138         {
139             var result = Avx2.InsertVector128(
140                 Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
141                 Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
142                 1
143             );
144
145             Unsafe.Write(_dataTable.outArrayPtr, result);
146             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
147         }
148
149         public void RunBasicScenario_Load()
150         {
151             var result = Avx2.InsertVector128(
152                 Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
153                 LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
154                 1
155             );
156
157             Unsafe.Write(_dataTable.outArrayPtr, result);
158             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
159         }
160
161         public void RunBasicScenario_LoadAligned()
162         {
163             var result = Avx2.InsertVector128(
164                 Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
165                 LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
166                 1
167             );
168
169             Unsafe.Write(_dataTable.outArrayPtr, result);
170             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
171         }
172
173         public void RunReflectionScenario_UnsafeRead()
174         {
175             var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
176                                      .Invoke(null, new object[] {
177                                         Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
178                                         Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
179                                         (byte)1
180                                      });
181
182             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
183             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
184         }
185
186         public void RunReflectionScenario_Load()
187         {
188             var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
189                                      .Invoke(null, new object[] {
190                                         Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
191                                         LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
192                                         (byte)1
193                                      });
194
195             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
196             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
197         }
198
199         public void RunReflectionScenario_LoadAligned()
200         {
201             var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
202                                      .Invoke(null, new object[] {
203                                         Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
204                                         LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
205                                         (byte)1
206                                      });
207
208             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
209             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
210         }
211
212         public void RunClsVarScenario()
213         {
214             var result = Avx2.InsertVector128(
215                 _clsVar1,
216                 _clsVar2,
217                 1
218             );
219
220             Unsafe.Write(_dataTable.outArrayPtr, result);
221             ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
222         }
223
224         public void RunLclVarScenario_UnsafeRead()
225         {
226             var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
227             var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
228             var result = Avx2.InsertVector128(left, right, 1);
229
230             Unsafe.Write(_dataTable.outArrayPtr, result);
231             ValidateResult(left, right, _dataTable.outArrayPtr);
232         }
233
234         public void RunLclVarScenario_Load()
235         {
236             var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
237             var right = LoadVector128((Int32*)(_dataTable.inArray2Ptr));
238             var result = Avx2.InsertVector128(left, right, 1);
239
240             Unsafe.Write(_dataTable.outArrayPtr, result);
241             ValidateResult(left, right, _dataTable.outArrayPtr);
242         }
243
244         public void RunLclVarScenario_LoadAligned()
245         {
246             var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
247             var right = LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
248             var result = Avx2.InsertVector128(left, right, 1);
249
250             Unsafe.Write(_dataTable.outArrayPtr, result);
251             ValidateResult(left, right, _dataTable.outArrayPtr);
252         }
253
254         public void RunLclFldScenario()
255         {
256             var test = new SimpleBinaryOpTest__InsertVector128Int321();
257             var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
258
259             Unsafe.Write(_dataTable.outArrayPtr, result);
260             ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
261         }
262
263         public void RunFldScenario()
264         {
265             var result = Avx2.InsertVector128(_fld1, _fld2, 1);
266
267             Unsafe.Write(_dataTable.outArrayPtr, result);
268             ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
269         }
270
271         public void RunUnsupportedScenario()
272         {
273             Succeeded = false;
274
275             try
276             {
277                 RunBasicScenario_UnsafeRead();
278             }
279             catch (PlatformNotSupportedException)
280             {
281                 Succeeded = true;
282             }
283         }
284
285         private void ValidateResult(Vector256<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
286         {
287             Int32[] inArray1 = new Int32[Op1ElementCount];
288             Int32[] inArray2 = new Int32[Op2ElementCount];
289             Int32[] outArray = new Int32[RetElementCount];
290
291             Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
292             Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
293             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
294
295             ValidateResult(inArray1, inArray2, outArray, method);
296         }
297
298         private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
299         {
300             Int32[] inArray1 = new Int32[Op1ElementCount];
301             Int32[] inArray2 = new Int32[Op2ElementCount];
302             Int32[] outArray = new Int32[RetElementCount];
303
304             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
305             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
306             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
307
308             ValidateResult(inArray1, inArray2, outArray, method);
309         }
310
311         private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
312         {
313             if (result[0] != left[0])
314             {
315                 Succeeded = false;
316             }
317             else
318             {
319                 for (var i = 1; i < RetElementCount; i++)
320                 {
321                     if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
322                     {
323                         Succeeded = false;
324                         break;
325                     }
326                 }
327             }
328
329             if (!Succeeded)
330             {
331                 Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {method} failed:");
332                 Console.WriteLine($"    left: ({string.Join(", ", left)})");
333                 Console.WriteLine($"   right: ({string.Join(", ", right)})");
334                 Console.WriteLine($"  result: ({string.Join(", ", result)})");
335                 Console.WriteLine();
336             }
337         }
338     }
339 }