Simplify ZEND_SIGNED_MULTIPLY_LONG() on Windows (GH-17477)

For Clang, we just need to define the respective macros, since these
built-ins are available in all supported Clang versions (>= 4.0.0,
currently)[1].

For MSVC (and possibly other compilers) we use the respective APIs of
intsafe.h[2] which are available as of Windows 7/Server 2008 R2.

For x86 (and to a lesser extend for ARM64) that should also notably
improve performance.

[1] <https://releases.llvm.org/4.0.0/tools/clang/docs/LanguageExtensions.html>
[2] <https://learn.microsoft.com/en-us/windows/win32/api/intsafe/>
This commit is contained in:
Christoph M. Becker 2025-01-16 13:57:07 +01:00 committed by GitHub
parent 39f1d253b1
commit 6967de563e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 37 deletions

View file

@ -79,46 +79,25 @@
else (lval) = __tmpvar; \ else (lval) = __tmpvar; \
} while (0) } while (0)
#elif defined(ZEND_WIN32) #elif defined(ZEND_WIN32) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
# ifdef _M_X64 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
# pragma intrinsic(_mul128) long long __tmpvar; \
# define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ if (((usedval) = FAILED(LongLongMult((a), (b), &__tmpvar)))) { \
__int64 __high; \ (dval) = (double) (a) * (double) (b); \
__int64 __low = _mul128((a), (b), &__high); \
if ((__low >> 63I64) == __high) { \
(usedval) = 0; \
(lval) = __low; \
} else { \
(usedval) = 1; \
(dval) = (double)(a) * (double)(b); \
} \
} while (0)
# elif defined(_M_ARM64)
# pragma intrinsic(__mulh)
# define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
__int64 __high = __mulh((a), (b)); \
__int64 __low = (a) * (b); \
if ((__low >> 63I64) == __high) { \
(usedval) = 0; \
(lval) = __low; \
} else { \
(usedval) = 1; \
(dval) = (double)(a) * (double)(b); \
} \
} while (0)
# else
# define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
zend_long __lres = (a) * (b); \
long double __dres = (long double)(a) * (long double)(b); \
long double __delta = (long double) __lres - __dres; \
if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
(dval) = __dres; \
} else { \
(lval) = __lres; \
} \ } \
else (lval) = __tmpvar; \
} while (0)
#elif defined(ZEND_WIN32) && SIZEOF_LONG == SIZEOF_ZEND_LONG
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
long __tmpvar; \
if (((usedval) = FAILED(LongMult((a), (b), &__tmpvar)))) { \
(dval) = (double) (a) * (double) (b); \
} \
else (lval) = __tmpvar; \
} while (0) } while (0)
# endif
#elif defined(__powerpc64__) && defined(__GNUC__) #elif defined(__powerpc64__) && defined(__GNUC__)

View file

@ -374,6 +374,8 @@ if (VS_TOOLSET) {
AC_DEFINE("PHP_HAVE_BUILTIN_SADDLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_saddll_overflow'."); AC_DEFINE("PHP_HAVE_BUILTIN_SADDLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_saddll_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SSUBL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubl_overflow'."); AC_DEFINE("PHP_HAVE_BUILTIN_SSUBL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubl_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubll_overflow'."); AC_DEFINE("PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubll_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SMULL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_smull_overflow '.");
AC_DEFINE("PHP_HAVE_BUILTIN_SMULLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_smulll_overflow'.");
if (PHP_UNCRITICAL_WARN_CHOKE != "no") { if (PHP_UNCRITICAL_WARN_CHOKE != "no") {
ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " + ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " +
"-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " + "-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " +