From aac06737faf512eed466c3c1b3be048553d939e5 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Thu, 2 Jan 2025 01:12:04 +0000 Subject: [PATCH 1/3] Remove unsafe `bool` casts --- .../Buffers/Text/FormattingHelpers.CountDigits.cs | 11 ++++++----- .../System.Private.CoreLib/src/System/Half.cs | 8 +++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs index 18eac2cf08eb7e..5792e13257deef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -24,8 +24,9 @@ public static int CountDigits(ulong value) ]; Debug.Assert(log2ToPow10.Length == 64); + // We use 'nint' because it gives us a free early zero-extension to 64 bits when running on a 64-bit platform. // TODO: Replace with log2ToPow10[BitOperations.Log2(value)] once https://github.com/dotnet/runtime/issues/79257 is fixed - uint index = Unsafe.Add(ref MemoryMarshal.GetReference(log2ToPow10), BitOperations.Log2(value)); + nint elementOffset = Unsafe.Add(ref MemoryMarshal.GetReference(log2ToPow10), BitOperations.Log2(value)); // Read the associated power of 10. ReadOnlySpan powersOf10 = @@ -52,13 +53,13 @@ public static int CountDigits(ulong value) 1000000000000000000, 10000000000000000000, ]; - Debug.Assert((index + 1) <= powersOf10.Length); - ulong powerOf10 = Unsafe.Add(ref MemoryMarshal.GetReference(powersOf10), index); + Debug.Assert((elementOffset + 1) <= powersOf10.Length); + ulong powerOf10 = Unsafe.Add(ref MemoryMarshal.GetReference(powersOf10), elementOffset); // Return the number of digits based on the power of 10, shifted by 1 // if it falls below the threshold. - bool lessThan = value < powerOf10; - return (int)(index - Unsafe.As(ref lessThan)); // while arbitrary bools may be non-0/1, comparison operators are expected to return 0/1 + int index = (int)elementOffset; + return index - (value < powerOf10 ? 1 : 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index dab5e73a278876..e47f0d7246eabf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -746,7 +746,7 @@ public static explicit operator Half(float value) // Extract sign bit uint sign = (bitValue & float.SignMask) >> 16; // Detecting NaN (~0u if a is not NaN) - uint realMask = (uint)(Unsafe.BitCast(float.IsNaN(value)) - 1); + uint realMask = float.IsNaN(value) ? 0u : ~0u; // Clear sign bit value = float.Abs(value); // Rectify values that are Infinity in Half. (float.Min now emits vminps instruction if one of two arguments is a constant) @@ -1075,9 +1075,7 @@ public static explicit operator float(Half value) // Extract exponent bits of value (BiasedExponent is not for here as it performs unnecessary shift) uint offsetExponent = bitValueInProcess & HalfExponentMask; // ~0u when value is subnormal, 0 otherwise - uint subnormalMask = (uint)-Unsafe.BitCast(offsetExponent == 0u); - // ~0u when value is either Infinity or NaN, 0 otherwise - int infinityOrNaNMask = Unsafe.BitCast(offsetExponent == HalfExponentMask); + uint subnormalMask = offsetExponent == 0u ? ~0u : 0u; // 0x3880_0000u if value is subnormal, 0 otherwise uint maskedExponentLowerBound = subnormalMask & ExponentLowerBound; // 0x3880_0000u if value is subnormal, 0x3800_0000u otherwise @@ -1085,7 +1083,7 @@ public static explicit operator float(Half value) // Match the position of the boundary of exponent bits and fraction bits with IEEE 754 Binary32(Single) bitValueInProcess <<= 13; // Double the offsetMaskedExponentLowerBound if value is either Infinity or NaN - offsetMaskedExponentLowerBound <<= infinityOrNaNMask; + offsetMaskedExponentLowerBound <<= offsetExponent == HalfExponentMask ? 1 : 0; // Extract exponent bits and fraction bits of value bitValueInProcess &= HalfToSingleBitsMask; // Adjust exponent to match the range of exponent From ead15c62a64e7abd2d0f7a6d6d0d1a8ffbe4eaf0 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 10 Jan 2025 20:47:28 +0000 Subject: [PATCH 2/3] clarify comment --- .../src/System/Buffers/Text/FormattingHelpers.CountDigits.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs index 5792e13257deef..ec78f175fef387 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -24,7 +24,8 @@ public static int CountDigits(ulong value) ]; Debug.Assert(log2ToPow10.Length == 64); - // We use 'nint' because it gives us a free early zero-extension to 64 bits when running on a 64-bit platform. + // We use a native-sized integer + // because it gives us a free early zero-extension to 64 bits when running on a 64-bit platform. // TODO: Replace with log2ToPow10[BitOperations.Log2(value)] once https://github.com/dotnet/runtime/issues/79257 is fixed nint elementOffset = Unsafe.Add(ref MemoryMarshal.GetReference(log2ToPow10), BitOperations.Log2(value)); From 9606e31dd8bd3d28ed92c1de898fd8004edafce4 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 21 Jan 2025 01:40:33 +0100 Subject: [PATCH 3/3] Remove comments in CountDigits method --- .../src/System/Buffers/Text/FormattingHelpers.CountDigits.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs index ec78f175fef387..35f7bba785ae55 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -24,8 +24,6 @@ public static int CountDigits(ulong value) ]; Debug.Assert(log2ToPow10.Length == 64); - // We use a native-sized integer - // because it gives us a free early zero-extension to 64 bits when running on a 64-bit platform. // TODO: Replace with log2ToPow10[BitOperations.Log2(value)] once https://github.com/dotnet/runtime/issues/79257 is fixed nint elementOffset = Unsafe.Add(ref MemoryMarshal.GetReference(log2ToPow10), BitOperations.Log2(value));