Merge pull request #18504 from mikedn/comp-small
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx / StaticCast.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 using System;
7 using System.Runtime.CompilerServices;
8 using System.Runtime.InteropServices;
9 using System.Runtime.Intrinsics.X86;
10 using System.Runtime.Intrinsics;
11
12 namespace IntelHardwareIntrinsicTest
13 {
14     // that it is intentionally designed to be a struct type that meets 
15     // the generic constraint but is not supported by any intrinsics
16     struct Num
17     {
18         public int a;
19     }
20
21     class Program
22     {
23         const int Pass = 100;
24         const int Fail = 0;
25
26         static unsafe int Main(string[] args)
27         {
28             int testResult = Pass;
29
30             if (Avx.IsSupported)
31             {
32                 using (TestTable<float, int> floatTable = new TestTable<float, int>(new float[8] { 1, float.NaN, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity, float.PositiveInfinity, float.NaN, 1 }, new int[8]))
33                 {
34                     var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArrayPtr);
35                     var vf2 = Avx.StaticCast<float, int>(vf1);
36                     Unsafe.Write(floatTable.outArrayPtr, vf2);
37
38                     if (!floatTable.CheckResult((x, y) => BitConverter.SingleToInt32Bits(x) == y))
39                     {
40                         Console.WriteLine("Avx StaticCast failed on float:");
41                         foreach (var item in floatTable.outArray)
42                         {
43                             Console.Write(item + ", ");
44                         }
45                         Console.WriteLine();
46                         testResult = Fail;
47                     }
48
49                     // the successful path is the one that catches the exception, so that does nothing, 
50                     // it is the fall-through path that's the error path
51                     try
52                     {
53                         var v = Avx.StaticCast<float, Num>(vf1);
54                         Unsafe.Write(floatTable.outArrayPtr, v);
55                         Console.WriteLine("Avx StaticCast failed on target type test:");
56                         testResult = Fail;
57                     }
58                     catch (System.NotSupportedException)
59                     {
60                     }
61
62                     // the successful path is the one that catches the exception, so that does nothing, 
63                     // it is the fall-through path that's the error path
64                     try
65                     {
66                         var v = TestSrcType();
67                         Unsafe.Write(floatTable.outArrayPtr, v);
68                         Console.WriteLine("Avx StaticCast failed on source type test:");
69                         testResult = Fail;
70                     }
71                     catch (System.NotSupportedException)
72                     {
73                     }
74                 }
75             }
76             
77             return testResult;
78         }
79         
80         [MethodImpl(MethodImplOptions.NoInlining)]
81         static Vector256<int> TestSrcType()
82         {
83             Vector256<Num> v1 = new Vector256<Num>();
84             Vector256<Num> v2 = new Vector256<Num>();
85             return Avx2.Add(Avx.StaticCast<Num, int>(v1), Avx.StaticCast<Num, int>(v2));
86         }
87
88         public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
89         {
90             public T[] inArray;
91             public U[] outArray;
92
93             public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
94             public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
95
96             GCHandle inHandle;
97             GCHandle outHandle;
98
99             public TestTable(T[] a, U[] b)
100             {
101                 this.inArray = a;
102                 this.outArray = b;
103
104                 inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
105                 outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
106             }
107
108             public bool CheckResult(Func<T, U, bool> check)
109             {
110                 for (int i = 0; i < inArray.Length; i++)
111                 {
112                     if (!check(inArray[i], outArray[i]))
113                     {
114                         return false;
115                     }
116                 }
117                 return true;
118             }
119
120             public void Dispose()
121             {
122                 inHandle.Free();
123                 outHandle.Free();
124             }
125         }
126     }
127 }