Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit acdd8e9

Browse files
committed
Skip bounds check in software fallback
1 parent 78e1f89 commit acdd8e9

File tree

1 file changed

+8
-3
lines changed
  • src/System.Private.CoreLib/shared/System

1 file changed

+8
-3
lines changed

src/System.Private.CoreLib/shared/System/BitOps.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
67
using System.Runtime.Intrinsics.X86;
78

9+
using Internal.Runtime.CompilerServices;
10+
811
namespace System
912
{
1013
internal static class BitOps
@@ -16,11 +19,13 @@ public static int TrailingZeroCount(int matches)
1619
{
1720
return (int)Bmi1.TrailingZeroCount((uint)matches);
1821
}
19-
else
22+
else // Software fallback
2023
{
21-
// Fallback
2224
// https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
23-
return TrailingCountMultiplyDeBruijn[(int)(((uint)((matches & -matches) * 0x077CB531U)) >> 27)];
25+
// uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
26+
return Unsafe.AddByteOffset(
27+
ref MemoryMarshal.GetReference(TrailingCountMultiplyDeBruijn),
28+
((uint)((matches & -matches) * 0x077CB531U)) >> 27);
2429
}
2530
}
2631

0 commit comments

Comments
 (0)