Skip to content

Commit fe6f0ed

Browse files
committed
Use Unsafe.BitCast to avoid taking address
1 parent b33f755 commit fe6f0ed

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

src/libraries/System.Private.CoreLib/src/System/Array.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,31 +1513,31 @@ public static unsafe int IndexOf<T>(T[] array, T value, int startIndex, int coun
15131513
{
15141514
int result = SpanHelpers.IndexOfValueType(
15151515
ref Unsafe.Add(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetArrayDataReference(array)), startIndex),
1516-
Unsafe.As<T, byte>(ref value),
1516+
Unsafe.BitCast<T, byte>(value),
15171517
count);
15181518
return (result >= 0 ? startIndex : 0) + result;
15191519
}
15201520
else if (sizeof(T) == sizeof(short))
15211521
{
15221522
int result = SpanHelpers.IndexOfValueType(
15231523
ref Unsafe.Add(ref Unsafe.As<T, short>(ref MemoryMarshal.GetArrayDataReference(array)), startIndex),
1524-
Unsafe.As<T, short>(ref value),
1524+
Unsafe.BitCast<T, short>(value),
15251525
count);
15261526
return (result >= 0 ? startIndex : 0) + result;
15271527
}
15281528
else if (sizeof(T) == sizeof(int))
15291529
{
15301530
int result = SpanHelpers.IndexOfValueType(
15311531
ref Unsafe.Add(ref Unsafe.As<T, int>(ref MemoryMarshal.GetArrayDataReference(array)), startIndex),
1532-
Unsafe.As<T, int>(ref value),
1532+
Unsafe.BitCast<T, int>(value),
15331533
count);
15341534
return (result >= 0 ? startIndex : 0) + result;
15351535
}
15361536
else if (sizeof(T) == sizeof(long))
15371537
{
15381538
int result = SpanHelpers.IndexOfValueType(
15391539
ref Unsafe.Add(ref Unsafe.As<T, long>(ref MemoryMarshal.GetArrayDataReference(array)), startIndex),
1540-
Unsafe.As<T, long>(ref value),
1540+
Unsafe.BitCast<T, long>(value),
15411541
count);
15421542
return (result >= 0 ? startIndex : 0) + result;
15431543
}
@@ -1758,7 +1758,7 @@ public static unsafe int LastIndexOf<T>(T[] array, T value, int startIndex, int
17581758
int endIndex = startIndex - count + 1;
17591759
int result = SpanHelpers.LastIndexOfValueType(
17601760
ref Unsafe.Add(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetArrayDataReference(array)), endIndex),
1761-
Unsafe.As<T, byte>(ref value),
1761+
Unsafe.BitCast<T, byte>(value),
17621762
count);
17631763

17641764
return (result >= 0 ? endIndex : 0) + result;
@@ -1768,7 +1768,7 @@ ref Unsafe.Add(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetArrayDataReference(ar
17681768
int endIndex = startIndex - count + 1;
17691769
int result = SpanHelpers.LastIndexOfValueType(
17701770
ref Unsafe.Add(ref Unsafe.As<T, short>(ref MemoryMarshal.GetArrayDataReference(array)), endIndex),
1771-
Unsafe.As<T, short>(ref value),
1771+
Unsafe.BitCast<T, short>(value),
17721772
count);
17731773

17741774
return (result >= 0 ? endIndex : 0) + result;
@@ -1778,7 +1778,7 @@ ref Unsafe.Add(ref Unsafe.As<T, short>(ref MemoryMarshal.GetArrayDataReference(a
17781778
int endIndex = startIndex - count + 1;
17791779
int result = SpanHelpers.LastIndexOfValueType(
17801780
ref Unsafe.Add(ref Unsafe.As<T, int>(ref MemoryMarshal.GetArrayDataReference(array)), endIndex),
1781-
Unsafe.As<T, int>(ref value),
1781+
Unsafe.BitCast<T, int>(value),
17821782
count);
17831783

17841784
return (result >= 0 ? endIndex : 0) + result;
@@ -1788,7 +1788,7 @@ ref Unsafe.Add(ref Unsafe.As<T, int>(ref MemoryMarshal.GetArrayDataReference(arr
17881788
int endIndex = startIndex - count + 1;
17891789
int result = SpanHelpers.LastIndexOfValueType(
17901790
ref Unsafe.Add(ref Unsafe.As<T, long>(ref MemoryMarshal.GetArrayDataReference(array)), endIndex),
1791-
Unsafe.As<T, long>(ref value),
1791+
Unsafe.BitCast<T, long>(value),
17921792
count);
17931793

17941794
return (result >= 0 ? endIndex : 0) + result;

src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,33 @@ public static unsafe void Fill<T>(ref T refData, nuint numElements, T value)
2929
{
3030
// We have enough data for at least one vectorized write.
3131

32-
T tmp = value; // Avoid taking address of the "value" argument. It would regress performance of the loops below.
3332
Vector<byte> vector;
3433

3534
if (sizeof(T) == 1)
3635
{
37-
vector = new Vector<byte>(Unsafe.As<T, byte>(ref tmp));
36+
vector = new Vector<byte>(Unsafe.BitCast<T, byte>(value));
3837
}
3938
else if (sizeof(T) == 2)
4039
{
41-
vector = (Vector<byte>)(new Vector<ushort>(Unsafe.As<T, ushort>(ref tmp)));
40+
vector = (Vector<byte>)(new Vector<ushort>(Unsafe.BitCast<T, ushort>(value)));
4241
}
4342
else if (sizeof(T) == 4)
4443
{
4544
// special-case float since it's already passed in a SIMD reg
4645
vector = (typeof(T) == typeof(float))
47-
? (Vector<byte>)(new Vector<float>((float)(object)tmp!))
48-
: (Vector<byte>)(new Vector<uint>(Unsafe.As<T, uint>(ref tmp)));
46+
? (Vector<byte>)(new Vector<float>(Unsafe.BitCast<T, float>(value)))
47+
: (Vector<byte>)(new Vector<uint>(Unsafe.BitCast<T, ushort>(value)))
4948
}
5049
else if (sizeof(T) == 8)
5150
{
5251
// special-case double since it's already passed in a SIMD reg
5352
vector = (typeof(T) == typeof(double))
54-
? (Vector<byte>)(new Vector<double>((double)(object)tmp!))
55-
: (Vector<byte>)(new Vector<ulong>(Unsafe.As<T, ulong>(ref tmp)));
53+
? (Vector<byte>)(new Vector<float>(Unsafe.BitCast<T, double>(value)))
54+
: (Vector<byte>)(new Vector<ulong>(Unsafe.BitCast<T, ulong>(value)));
5655
}
5756
else if (sizeof(T) == 16)
5857
{
59-
Vector128<byte> vec128 = Unsafe.As<T, Vector128<byte>>(ref tmp);
58+
Vector128<byte> vec128 = Unsafe.BitCast<T, Vector128<byte>>(value);
6059
if (Vector<byte>.Count == 16)
6160
{
6261
vector = vec128.AsVector();
@@ -75,7 +74,7 @@ public static unsafe void Fill<T>(ref T refData, nuint numElements, T value)
7574
{
7675
if (Vector<byte>.Count == 32)
7776
{
78-
vector = Unsafe.As<T, Vector256<byte>>(ref tmp).AsVector();
77+
vector = Unsafe.BitCast<T, Vector256<byte>>(value).AsVector();
7978
}
8079
else
8180
{

0 commit comments

Comments
 (0)