Skip to content

Commit 97d9422

Browse files
Simplify SVE unary test template (#118129)
* Replace DataTable with PinnedVector class * Add functions for generating random Vectors * Add functions for converting between Vector and Array types * Generate an expected Vector for comparison and log to terminal * Simplify validation functions * Remove RetVectorType and Op1VectorType template variables
1 parent 64ccbad commit 97d9422

File tree

4 files changed

+261
-217
lines changed

4 files changed

+261
-217
lines changed

src/tests/Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<Compile Include="CoreClrConfigurationDetection.cs" />
1717
<Compile Include="OutOfProcessTest.cs" />
1818
<Compile Include="PlatformDetection.cs" />
19+
<Compile Include="Vectors.cs" />
1920
</ItemGroup>
2021
<ItemGroup>
2122
<Compile Include="..\Coreclr.TestWrapper\CoreclrTestWrapperLib.cs" Link="CoreclrTestWrapperLib.cs" />
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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+
4+
using System;
5+
using System.Numerics;
6+
using System.Runtime.CompilerServices;
7+
using System.Runtime.InteropServices;
8+
9+
namespace TestLibrary
10+
{
11+
public static class Vectors
12+
{
13+
public static void VectorToArray<T>(ref T[] dst, Vector<T> src) where T : struct
14+
{
15+
Span<byte> span = MemoryMarshal.AsBytes(dst.AsSpan());
16+
MemoryMarshal.Write(span, src);
17+
}
18+
19+
public static Vector<T> GetRandomVector<T>()
20+
{
21+
long vsize = Unsafe.SizeOf<Vector<T>>();
22+
byte[] data = new byte[vsize];
23+
for (int i = 0; i < vsize; i++)
24+
{
25+
data[i] = TestLibrary.Generator.GetByte();
26+
}
27+
return new Vector<T>(data.AsSpan());
28+
}
29+
30+
public static Vector<T> GetRandomMask<T>()
31+
{
32+
long vsize = Unsafe.SizeOf<Vector<T>>();
33+
long tsize = Unsafe.SizeOf<T>();
34+
35+
byte[] data = new byte[vsize];
36+
37+
long count = vsize / tsize;
38+
for (int i = 0; i < count; i++)
39+
{
40+
data[i * tsize] |= (byte)(TestLibrary.Generator.GetByte() & 1);
41+
}
42+
43+
return new Vector<T>(data.AsSpan());
44+
}
45+
46+
public class PinnedVector<T> where T : struct
47+
{
48+
private byte[] buf;
49+
private GCHandle inHandle;
50+
private ulong alignment;
51+
52+
private void Alloc(T[] data, int alignment)
53+
{
54+
unsafe
55+
{
56+
int sizeOfinArray1 = data.Length * Unsafe.SizeOf<T>();
57+
if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1)
58+
{
59+
throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}");
60+
}
61+
62+
buf = new byte[alignment * 2];
63+
inHandle = GCHandle.Alloc(buf, GCHandleType.Pinned);
64+
this.alignment = (ulong)alignment;
65+
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(Ptr), ref Unsafe.As<T, byte>(ref data[0]), (uint)sizeOfinArray1);
66+
}
67+
}
68+
69+
public PinnedVector(T[] data, int alignment)
70+
{
71+
Alloc(data, alignment);
72+
}
73+
74+
public PinnedVector(Vector<T> inVector, int alignment)
75+
{
76+
long tsize = Unsafe.SizeOf<T>();
77+
long vsize = Unsafe.SizeOf<Vector<T>>();
78+
long count = vsize / tsize;
79+
T[] data = new T[count];
80+
VectorToArray(ref data, inVector);
81+
Alloc(data, alignment);
82+
}
83+
84+
public unsafe void* Ptr => Align((byte*)inHandle.AddrOfPinnedObject().ToPointer(), alignment);
85+
86+
public void Dispose()
87+
{
88+
inHandle.Free();
89+
}
90+
91+
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
92+
{
93+
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
94+
}
95+
96+
public Vector<T> Value
97+
{
98+
get
99+
{
100+
unsafe
101+
{
102+
return Unsafe.Read<Vector<T>>(Ptr);
103+
}
104+
}
105+
set
106+
{
107+
unsafe
108+
{
109+
Unsafe.Write(Ptr, value);
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}

src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,8 @@ public static T ShiftRight<T>(T op1, ulong op2) where T : INumber<T>
12271227
public static T SignExtend<T>(T n, int numBits, bool zeroExtend) where T : struct, IComparable, IConvertible
12281228
{
12291229
// Get the underlying integer value
1230-
dynamic value = Convert.ChangeType(n, typeof(long));
1230+
dynamic value = n;
1231+
value = (long)value;
12311232

12321233
// Mask to extract the lowest numBits
12331234
long mask = (1L << numBits) - 1;
@@ -4540,10 +4541,25 @@ private static uint ReciprocalSqrtEstimate(uint a)
45404541

45414542
public static double ReciprocalExponent(double op1)
45424543
{
4544+
if (double.IsNaN(op1))
4545+
{
4546+
return double.NaN;
4547+
}
4548+
45434549
ulong bits = (ulong)BitConverter.DoubleToUInt64Bits(op1);
4550+
ulong exp = bits & 0x7FF0000000000000;
4551+
4552+
if (exp == 0)
4553+
{
4554+
// Replace exponent with maximum exponent
4555+
bits ^= exp ^ 0x7FE0000000000000;
4556+
}
4557+
else
4558+
{
4559+
// Invert the exponent
4560+
bits ^= 0x7FF0000000000000;
4561+
}
45444562

4545-
// Invert the exponent
4546-
bits ^= 0x7FF0000000000000;
45474563
// Zero the fraction
45484564
bits &= 0xFFF0000000000000;
45494565

@@ -4552,10 +4568,25 @@ public static double ReciprocalExponent(double op1)
45524568

45534569
public static float ReciprocalExponent(float op1)
45544570
{
4571+
if (float.IsNaN(op1))
4572+
{
4573+
return float.NaN;
4574+
}
4575+
45554576
uint bits = BitConverter.SingleToUInt32Bits(op1);
4577+
uint exp = bits & 0x7F800000;
4578+
4579+
if (exp == 0)
4580+
{
4581+
// Replace exponent with maximum exponent
4582+
bits ^= exp ^ 0x7F000000;
4583+
}
4584+
else
4585+
{
4586+
// Invert the exponent
4587+
bits ^= 0x7F800000;
4588+
}
45564589

4557-
// Invert the exponent
4558-
bits ^= 0x7F800000;
45594590
// Zero the fraction
45604591
bits &= 0xFF800000;
45614592

0 commit comments

Comments
 (0)