diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs index e8cd792243e314..c66e39d690bcf0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs @@ -945,6 +945,13 @@ private static unsafe nuint NarrowUtf16ToLatin1_Sse2(char* pUtf16Buffer, byte* p /// public static unsafe void WidenLatin1ToUtf16(byte* pLatin1Buffer, char* pUtf16Buffer, nuint elementCount) { + if (((nuint)pUtf16Buffer & 1) != 0) + { + // Input isn't char aligned, we won't be able to vectorize. + WidenLatin1ToUtf16_MisalignedAddress(pLatin1Buffer, pUtf16Buffer, elementCount); + return; + } + // If SSE2 is supported, use those specific intrinsics instead of the generic vectorized // code below. This has two benefits: (a) we can take advantage of specific instructions like // punpcklbw which we know are optimized, and (b) we can avoid downclocking the processor while @@ -1106,5 +1113,19 @@ private static unsafe void WidenLatin1ToUtf16_Fallback(byte* pLatin1Buffer, char currentOffset++; } } + + private static unsafe void WidenLatin1ToUtf16_MisalignedAddress(byte* pLatin1Buffer, char* pUtf16Buffer, nuint elementCount) + { + if (elementCount != 0) + { + do + { + Unsafe.WriteUnaligned(pUtf16Buffer, (char)*pLatin1Buffer); + pUtf16Buffer++; + pLatin1Buffer++; + } + while (--elementCount != 0); + } + } } }