Merge pull request #15737 from mikedn/cast-narrow-store
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx / ExtractVector128.Single.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.Reflection;
14 using System.Linq;
15 using System.Runtime.CompilerServices;
16 using System.Runtime.InteropServices;
17 using System.Runtime.Intrinsics;
18 using System.Runtime.Intrinsics.X86;
19
20 namespace JIT.HardwareIntrinsics.X86
21 {
22     public static partial class Program
23     {
24         private static void ExtractVector128Single1()
25         {
26             var test = new SimpleUnaryOpTest__ExtractVector128Single1();
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 SimpleUnaryOpTest__ExtractVector128Single1
89     {
90         private static readonly int LargestVectorSize = 32;
91
92         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
93         private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
94
95         private static Single[] _data = new Single[Op1ElementCount];
96
97         private static Vector256<Single> _clsVar;
98
99         private Vector256<Single> _fld;
100
101         private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
102
103         static SimpleUnaryOpTest__ExtractVector128Single1()
104         {
105             var random = new Random();
106
107             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
108             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
109         }
110
111         public SimpleUnaryOpTest__ExtractVector128Single1()
112         {
113             Succeeded = true;
114
115             var random = new Random();
116
117             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
118             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
119
120             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
121             _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
122         }
123
124         public bool IsSupported => Avx.IsSupported;
125
126         public bool Succeeded { get; set; }
127
128         public void RunBasicScenario_UnsafeRead()
129         {
130             var result = Avx.ExtractVector128(
131                 Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
132                 1
133             );
134
135             Unsafe.Write(_dataTable.outArrayPtr, result);
136             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
137         }
138
139         public void RunBasicScenario_Load()
140         {
141             var result = Avx.ExtractVector128(
142                 Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
143                 1
144             );
145
146             Unsafe.Write(_dataTable.outArrayPtr, result);
147             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
148         }
149
150         public void RunBasicScenario_LoadAligned()
151         {
152             var result = Avx.ExtractVector128(
153                 Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
154                 1
155             );
156
157             Unsafe.Write(_dataTable.outArrayPtr, result);
158             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
159         }
160
161         public void RunReflectionScenario_UnsafeRead()
162         {
163             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
164                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
165                                      .MakeGenericMethod(new[] { typeof(Single) })
166                                      .Invoke(null, new object[] {
167                                         Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
168                                         (byte)1
169                                      });
170
171             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
172             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
173         }
174
175         public void RunReflectionScenario_Load()
176         {
177             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
178                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
179                                      .MakeGenericMethod(new[] { typeof(Single) })
180                                      .Invoke(null, new object[] {
181                                         Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
182                                         (byte)1
183                                      });
184
185             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
186             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
187         }
188
189         public void RunReflectionScenario_LoadAligned()
190         {
191             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
192                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
193                                      .MakeGenericMethod(new[] { typeof(Single) })
194                                      .Invoke(null, new object[] {
195                                         Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
196                                         (byte)1
197                                      });
198
199             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
200             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
201         }
202
203         public void RunClsVarScenario()
204         {
205             var result = Avx.ExtractVector128(
206                 _clsVar,
207                 1
208             );
209
210             Unsafe.Write(_dataTable.outArrayPtr, result);
211             ValidateResult(_clsVar, _dataTable.outArrayPtr);
212         }
213
214         public void RunLclVarScenario_UnsafeRead()
215         {
216             var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
217             var result = Avx.ExtractVector128(firstOp, 1);
218
219             Unsafe.Write(_dataTable.outArrayPtr, result);
220             ValidateResult(firstOp, _dataTable.outArrayPtr);
221         }
222
223         public void RunLclVarScenario_Load()
224         {
225             var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
226             var result = Avx.ExtractVector128(firstOp, 1);
227
228             Unsafe.Write(_dataTable.outArrayPtr, result);
229             ValidateResult(firstOp, _dataTable.outArrayPtr);
230         }
231
232         public void RunLclVarScenario_LoadAligned()
233         {
234             var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
235             var result = Avx.ExtractVector128(firstOp, 1);
236
237             Unsafe.Write(_dataTable.outArrayPtr, result);
238             ValidateResult(firstOp, _dataTable.outArrayPtr);
239         }
240
241         public void RunLclFldScenario()
242         {
243             var test = new SimpleUnaryOpTest__ExtractVector128Single1();
244             var result = Avx.ExtractVector128(test._fld, 1);
245
246             Unsafe.Write(_dataTable.outArrayPtr, result);
247             ValidateResult(test._fld, _dataTable.outArrayPtr);
248         }
249
250         public void RunFldScenario()
251         {
252             var result = Avx.ExtractVector128(_fld, 1);
253
254             Unsafe.Write(_dataTable.outArrayPtr, result);
255             ValidateResult(_fld, _dataTable.outArrayPtr);
256         }
257
258         public void RunUnsupportedScenario()
259         {
260             Succeeded = false;
261
262             try
263             {
264                 RunBasicScenario_UnsafeRead();
265             }
266             catch (PlatformNotSupportedException)
267             {
268                 Succeeded = true;
269             }
270         }
271
272         private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
273         {
274             Single[] inArray = new Single[Op1ElementCount];
275             Single[] outArray = new Single[RetElementCount];
276
277             Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
278             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
279
280             ValidateResult(inArray, outArray, method);
281         }
282
283         private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
284         {
285             Single[] inArray = new Single[Op1ElementCount];
286             Single[] outArray = new Single[RetElementCount];
287
288             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
289             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
290
291             ValidateResult(inArray, outArray, method);
292         }
293
294         private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
295         {
296             if (result[0] != firstOp[4])
297             {
298                 Succeeded = false;
299             }
300             else
301             {
302                 for (var i = 1; i < RetElementCount; i++)
303                 {
304                     if ((result[i] != firstOp[i + 4]))
305                     {
306                         Succeeded = false;
307                         break;
308                     }
309                 }
310             }
311
312             if (!Succeeded)
313             {
314                 Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Single>(Vector256<Single><9>): {method} failed:");
315                 Console.WriteLine($"  firstOp: ({string.Join(", ", firstOp)})");
316                 Console.WriteLine($"   result: ({string.Join(", ", result)})");
317                 Console.WriteLine();
318             }
319         }
320     }
321 }