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