Skip to content

Commit f26e8bc

Browse files
committed
Move constant variables outside the loop
1 parent 41dee08 commit f26e8bc

File tree

1 file changed

+13
-5
lines changed
  • src/libraries/System.Collections/src/System/Collections

1 file changed

+13
-5
lines changed

src/libraries/System.Collections/src/System/Collections/BitArray.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,29 +140,33 @@ public unsafe BitArray(bool[] values)
140140

141141
if (Avx2.IsSupported)
142142
{
143+
// JIT does not support code hoisting for SIMD yet
144+
Vector256<byte> zero = Vector256<byte>.Zero;
143145
fixed (bool* ptr = values)
144146
{
145147
for (; (i + Vector256<byte>.Count) <= values.Length; i += (uint)Vector256<byte>.Count)
146148
{
147149
Vector256<byte> vector = Avx.LoadVector256((byte*)ptr + i);
148-
Vector256<byte> isFalse = Avx2.CompareEqual(vector, Vector256<byte>.Zero);
150+
Vector256<byte> isFalse = Avx2.CompareEqual(vector, zero);
149151
int result = Avx2.MoveMask(isFalse);
150152
m_array[i / 32] = ~result;
151153
}
152154
}
153155
}
154156
else if (Sse2.IsSupported)
155157
{
158+
// JIT does not support code hoisting for SIMD yet
159+
Vector128<byte> zero = Vector128<byte>.Zero;
156160
fixed (bool* ptr = values)
157161
{
158162
for (; (i + Vector128<byte>.Count * 2) <= values.Length; i += (uint)Vector128<byte>.Count * 2)
159163
{
160164
Vector128<byte> lowerVector = Sse2.LoadVector128((byte*)ptr + i);
161-
Vector128<byte> lowerIsFalse = Sse2.CompareEqual(lowerVector, Vector128<byte>.Zero);
165+
Vector128<byte> lowerIsFalse = Sse2.CompareEqual(lowerVector, zero);
162166
int lowerPackedIsFalse = Sse2.MoveMask(lowerIsFalse);
163167

164168
Vector128<byte> upperVector = Sse2.LoadVector128((byte*)ptr + i + Vector128<byte>.Count);
165-
Vector128<byte> upperIsFalse = Sse2.CompareEqual(upperVector, Vector128<byte>.Zero);
169+
Vector128<byte> upperIsFalse = Sse2.CompareEqual(upperVector, zero);
166170
int upperPackedIsFalse = Sse2.MoveMask(upperIsFalse);
167171

168172
m_array[i / 32] = ~((upperPackedIsFalse << 16) | lowerPackedIsFalse);
@@ -171,6 +175,10 @@ public unsafe BitArray(bool[] values)
171175
}
172176
else if (AdvSimd.Arm64.IsSupported)
173177
{
178+
// JIT does not support code hoisting for SIMD yet
179+
// However comparison against zero can be replaced to cmeq against zero (vceqzq_s8)
180+
// See dotnet/runtime#33972 for details
181+
Vector128<byte> zero = Vector128<byte>.Zero;
174182
fixed (bool* ptr = values)
175183
{
176184
for (; (i + Vector128<byte>.Count * 2) <= values.Length; i += (uint)Vector128<byte>.Count * 2)
@@ -179,15 +187,15 @@ public unsafe BitArray(bool[] values)
179187
// As a workaround, mask out the relevant bit after comparison
180188
// and combine by ORing all of them together (In this case, adding all of them does the same thing)
181189
Vector128<byte> lowerVector = AdvSimd.LoadVector128((byte*)ptr + i);
182-
Vector128<byte> lowerIsFalse = AdvSimd.CompareEqual(lowerVector, Vector128<byte>.Zero);
190+
Vector128<byte> lowerIsFalse = AdvSimd.CompareEqual(lowerVector, zero);
183191
Vector128<byte> bitsExtracted1 = AdvSimd.And(lowerIsFalse, s_bitMask128);
184192
bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1);
185193
bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1);
186194
bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1);
187195
Vector128<short> lowerPackedIsFalse = bitsExtracted1.AsInt16();
188196

189197
Vector128<byte> upperVector = AdvSimd.LoadVector128((byte*)ptr + i + Vector128<byte>.Count);
190-
Vector128<byte> upperIsFalse = AdvSimd.CompareEqual(upperVector, Vector128<byte>.Zero);
198+
Vector128<byte> upperIsFalse = AdvSimd.CompareEqual(upperVector, zero);
191199
Vector128<byte> bitsExtracted2 = AdvSimd.And(upperIsFalse, s_bitMask128);
192200
bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2);
193201
bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2);

0 commit comments

Comments
 (0)