From 426d18abc6ab73924e8331e4ff57e313f136350a Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Thu, 22 Jun 2023 12:45:04 +0100 Subject: [PATCH] Use internal `BitOperations.ResetLowestSetBit` (#87798) --- .../src/System/Globalization/Ordinal.cs | 24 ++++--------------- .../src/System/SpanHelpers.Char.cs | 18 ++++---------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs index d4a5ae73adf0d..40f68fa3b9b38 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs @@ -462,8 +462,7 @@ ref Unsafe.Add(ref valueRef, 1), valueTailLength)) // Do a full IgnoreCase equality comparison. SpanHelpers.IndexOf skips comparing the two characters in some cases, // but we don't actually know that the two characters are equal, since we compared with | 0x20. So we just compare // the full string always. - int bitPos = BitOperations.TrailingZeroCount(mask); - nint charPos = (nint)((uint)bitPos / 2); // div by 2 (shr) because we work with 2-byte chars + nint charPos = (nint)(uint.TrailingZeroCount(mask) / sizeof(ushort)); if (EqualsIgnoreCase(ref Unsafe.Add(ref searchSpace, offset + charPos), ref valueRef, value.Length)) { // Match! Return the index. @@ -472,14 +471,7 @@ ref Unsafe.Add(ref valueRef, 1), valueTailLength)) // Clear the two lowest set bits in the mask. If there are no more set bits, we're done. // If any remain, we loop around to do the next comparison. - if (Bmi1.IsSupported) - { - mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); - } - else - { - mask &= ~(uint)(0b11 << bitPos); - } + mask = BitOperations.ResetLowestSetBit(BitOperations.ResetLowestSetBit(mask)); } while (mask != 0); goto LoopFooter; @@ -536,8 +528,7 @@ ref Unsafe.Add(ref valueRef, 1), valueTailLength)) // Do a full IgnoreCase equality comparison. SpanHelpers.IndexOf skips comparing the two characters in some cases, // but we don't actually know that the two characters are equal, since we compared with | 0x20. So we just compare // the full string always. - int bitPos = BitOperations.TrailingZeroCount(mask); - int charPos = (int)((uint)bitPos / 2); // div by 2 (shr) because we work with 2-byte chars + nint charPos = (nint)(uint.TrailingZeroCount(mask) / sizeof(ushort)); if (EqualsIgnoreCase(ref Unsafe.Add(ref searchSpace, offset + charPos), ref valueRef, value.Length)) { // Match! Return the index. @@ -546,14 +537,7 @@ ref Unsafe.Add(ref valueRef, 1), valueTailLength)) // Clear the two lowest set bits in the mask. If there are no more set bits, we're done. // If any remain, we loop around to do the next comparison. - if (Bmi1.IsSupported) - { - mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); - } - else - { - mask &= ~(uint)(0b11 << bitPos); - } + mask = BitOperations.ResetLowestSetBit(BitOperations.ResetLowestSetBit(mask)); } while (mask != 0); goto LoopFooter; diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index 70216de36fd49..67e87162b27bc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -114,9 +114,7 @@ ref Unsafe.As(ref Unsafe.Add(ref searchSpace, offset + 1)), uint mask = cmpAnd.ExtractMostSignificantBits(); do { - int bitPos = BitOperations.TrailingZeroCount(mask); - // div by 2 (shr) because we work with 2-byte chars - nint charPos = (nint)((uint)bitPos / 2); + nint charPos = (nint)(uint.TrailingZeroCount(mask) / sizeof(ushort)); if (valueLength == 2 || // we already matched two chars SequenceEqual( ref Unsafe.As(ref Unsafe.Add(ref searchSpace, offset + charPos)), @@ -126,10 +124,7 @@ ref Unsafe.As(ref value), (nuint)(uint)valueLength * 2)) } // Clear two the lowest set bits - if (Bmi1.IsSupported) - mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); - else - mask &= ~(uint)(0b11 << bitPos); + mask = BitOperations.ResetLowestSetBit(BitOperations.ResetLowestSetBit(mask)); } while (mask != 0); goto LOOP_FOOTER; @@ -181,9 +176,7 @@ ref Unsafe.As(ref value), (nuint)(uint)valueLength * 2)) uint mask = cmpAnd.ExtractMostSignificantBits(); do { - int bitPos = BitOperations.TrailingZeroCount(mask); - // div by 2 (shr) because we work with 2-byte chars - int charPos = (int)((uint)bitPos / 2); + nint charPos = (nint)(uint.TrailingZeroCount(mask) / sizeof(ushort)); if (valueLength == 2 || // we already matched two chars SequenceEqual( ref Unsafe.As(ref Unsafe.Add(ref searchSpace, offset + charPos)), @@ -193,10 +186,7 @@ ref Unsafe.As(ref value), (nuint)(uint)valueLength * 2)) } // Clear two lowest set bits - if (Bmi1.IsSupported) - mask = Bmi1.ResetLowestSetBit(Bmi1.ResetLowestSetBit(mask)); - else - mask &= ~(uint)(0b11 << bitPos); + mask = BitOperations.ResetLowestSetBit(BitOperations.ResetLowestSetBit(mask)); } while (mask != 0); goto LOOP_FOOTER;