From 9e9625c283636683f9e70575dcb33c15b325fd06 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 11 Aug 2023 09:13:07 -0400 Subject: [PATCH 1/2] Replace Utf16Utility.GetPointerToFirstInvalidChar fallback with Vector128 The else block will only be used on platforms where `Vector` is 128-bit, so just use Vector128 explicitly. --- .../Text/Unicode/Utf16Utility.Validation.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs index 8818a96d16f107..c071d67c988457 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs @@ -311,16 +311,16 @@ internal static unsafe partial class Utf16Utility pInputBuffer -= Vector128.Count; } } - else if (Vector.IsHardwareAccelerated) + else if (Vector128.IsHardwareAccelerated) { - if (inputLength >= Vector.Count) + if (inputLength >= Vector128.Count) { - Vector vector0080 = new Vector(0x0080); - Vector vector0400 = new Vector(0x0400); - Vector vector0800 = new Vector(0x0800); - Vector vectorD800 = new Vector(0xD800); + Vector128 vector0080 = Vector128.Create(0x0080); + Vector128 vector0400 = Vector128.Create(0x0400); + Vector128 vector0800 = Vector128.Create(0x0800); + Vector128 vectorD800 = Vector128.Create(0xD800); - char* pHighestAddressWhereCanReadOneVector = pEndOfInputBuffer - Vector.Count; + char* pHighestAddressWhereCanReadOneVector = pEndOfInputBuffer - Vector128.Count; Debug.Assert(pHighestAddressWhereCanReadOneVector >= pInputBuffer); do @@ -340,16 +340,16 @@ internal static unsafe partial class Utf16Utility // performed by the SSE2 code path. This will overcount surrogates, but we'll // handle that shortly. - Vector utf16Data = Unsafe.ReadUnaligned>(pInputBuffer); - Vector twoOrMoreUtf8Bytes = Vector.GreaterThanOrEqual(utf16Data, vector0080); - Vector threeOrMoreUtf8Bytes = Vector.GreaterThanOrEqual(utf16Data, vector0800); - Vector sumVector = (Vector)(Vector.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes); + Vector128 utf16Data = Vector128.Load((ushort*)pInputBuffer); + Vector128 twoOrMoreUtf8Bytes = Vector128.GreaterThanOrEqual(utf16Data, vector0080); + Vector128 threeOrMoreUtf8Bytes = Vector128.GreaterThanOrEqual(utf16Data, vector0800); + Vector128 sumVector = Vector128.As(Vector128.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes); // We'll try summing by a natural word (rather than a 16-bit word) at a time, // which should halve the number of operations we must perform. nuint popcnt = 0; - for (int i = 0; i < Vector.Count; i++) + for (int i = 0; i < Vector128.Count; i++) { popcnt += (nuint)sumVector[i]; } @@ -368,16 +368,16 @@ internal static unsafe partial class Utf16Utility // Now check for surrogates. utf16Data -= vectorD800; - Vector surrogateChars = Vector.LessThan(utf16Data, vector0800); - if (surrogateChars != Vector.Zero) + Vector128 surrogateChars = Vector128.LessThan(utf16Data, vector0800); + if (surrogateChars != Vector128.Zero) { // There's at least one surrogate (high or low) UTF-16 code unit in // the vector. We'll build up additional vectors: 'highSurrogateChars' // and 'lowSurrogateChars', where the elements are 0xFFFF iff the original // UTF-16 code unit was a high or low surrogate, respectively. - Vector highSurrogateChars = Vector.LessThan(utf16Data, vector0400); - Vector lowSurrogateChars = Vector.AndNot(surrogateChars, highSurrogateChars); + Vector128 highSurrogateChars = Vector128.LessThan(utf16Data, vector0400); + Vector128 lowSurrogateChars = Vector128.AndNot(surrogateChars, highSurrogateChars); // We want to make sure that each high surrogate code unit is followed by // a low surrogate code unit and each low surrogate code unit follows a @@ -392,7 +392,7 @@ internal static unsafe partial class Utf16Utility } ushort surrogatePairsCount = 0; - for (int i = 0; i < Vector.Count - 1; i++) + for (int i = 0; i < Vector128.Count - 1; i++) { surrogatePairsCount -= highSurrogateChars[i]; // turns into +1 or +0 if (highSurrogateChars[i] != lowSurrogateChars[i + 1]) @@ -401,7 +401,7 @@ internal static unsafe partial class Utf16Utility } } - if (highSurrogateChars[Vector.Count - 1] != 0) + if (highSurrogateChars[Vector128.Count - 1] != 0) { // There was a standalone high surrogate at the end of the vector. // We'll adjust our counters so that we don't consider this char consumed. @@ -426,7 +426,7 @@ internal static unsafe partial class Utf16Utility } tempUtf8CodeUnitCountAdjustment += popcnt32; - pInputBuffer += Vector.Count; + pInputBuffer += Vector128.Count; } while (pInputBuffer <= pHighestAddressWhereCanReadOneVector); } } From 43bed53f45738c2357ad2fffcae3eb82b6ac3916 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 11 Aug 2023 10:55:53 -0400 Subject: [PATCH 2/2] Address PR feedback --- .../src/System/Text/Unicode/Utf16Utility.Validation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs index c071d67c988457..47e253d526702f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs @@ -343,7 +343,7 @@ internal static unsafe partial class Utf16Utility Vector128 utf16Data = Vector128.Load((ushort*)pInputBuffer); Vector128 twoOrMoreUtf8Bytes = Vector128.GreaterThanOrEqual(utf16Data, vector0080); Vector128 threeOrMoreUtf8Bytes = Vector128.GreaterThanOrEqual(utf16Data, vector0800); - Vector128 sumVector = Vector128.As(Vector128.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes); + Vector128 sumVector = (Vector128.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes).AsNUInt(); // We'll try summing by a natural word (rather than a 16-bit word) at a time, // which should halve the number of operations we must perform.