@@ -4643,6 +4643,14 @@ MBSTRING_API bool php_mb_check_encoding(const char *input, size_t length, const
4643
4643
return true;
4644
4644
}
4645
4645
4646
+ /* MSVC 32-bit has issues with 64-bit intrinsics.
4647
+ * (Bad 7/8-byte UTF-8 strings would be wrongly passed through as 'valid')
4648
+ * It seems this is caused by a bug in MS Visual C++
4649
+ * Ref: https://stackoverflow.com/questions/37509129/potential-bug-in-visual-studio-c-compiler-or-in-intel-intrinsics-avx2-mm256-s */
4650
+ #if defined(PHP_WIN32 ) && !defined(__clang__ ) && defined(_MSC_VER ) && defined(_M_IX86 )
4651
+ # define MBSTRING_BROKEN_X86_MSVC_INTRINSICS
4652
+ #endif
4653
+
4646
4654
/* If we are building an AVX2-only binary, don't compile the next function */
4647
4655
#ifndef ZEND_INTRIN_AVX2_NATIVE
4648
4656
@@ -4808,7 +4816,11 @@ static bool mb_fast_check_utf8_default(zend_string *str)
4808
4816
goto check_operand ;
4809
4817
case 7 :
4810
4818
case 8 :
4819
+ #ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
4820
+ operand = _mm_set_epi32 (0 , 0 , ((int32_t * )p )[1 ], ((int32_t * )p )[0 ]);
4821
+ #else
4811
4822
operand = _mm_set_epi64x (0 , * ((uint64_t * )p ));
4823
+ #endif
4812
4824
goto check_operand ;
4813
4825
case 9 :
4814
4826
operand = _mm_srli_si128 (_mm_loadu_si128 ((__m128i * )(p - 6 )), 6 );
@@ -5201,12 +5213,11 @@ static bool mb_fast_check_utf8_avx2(zend_string *str)
5201
5213
goto check_operand ;
5202
5214
case 7 :
5203
5215
case 8 :
5204
- /* This was originally: operand = _mm256_set_epi64x(0, 0, 0, *((int64_t*)p));
5205
- * However, that caused test failures on 32-bit MS Windows
5206
- * (Bad 7/8-byte UTF-8 strings would be wrongly passed through as 'valid')
5207
- * It seems this is caused by a bug in MS Visual C++
5208
- * Ref: https://stackoverflow.com/questions/37509129/potential-bug-in-visual-studio-c-compiler-or-in-intel-intrinsics-avx2-mm256-s */
5216
+ #ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
5209
5217
operand = _mm256_set_epi32 (0 , 0 , 0 , 0 , 0 , 0 , ((int32_t * )p )[1 ], ((int32_t * )p )[0 ]);
5218
+ #else
5219
+ operand = _mm256_set_epi64x (0 , 0 , 0 , * ((int64_t * )p ));
5220
+ #endif
5210
5221
goto check_operand ;
5211
5222
case 9 :
5212
5223
operand = _mm256_set_m128i (_mm_setzero_si128 (), _mm_srli_si128 (_mm_loadu_si128 ((__m128i * )(p - 6 )), 6 ));
0 commit comments