Skip to content

Commit 87b7180

Browse files
committed
Fixed cpu feature check in reslover functions
1 parent ab44ddd commit 87b7180

File tree

6 files changed

+88
-9
lines changed

6 files changed

+88
-9
lines changed

Zend/zend.c

-2
Original file line numberDiff line numberDiff line change
@@ -742,9 +742,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
742742
extern zend_php_scanner_globals language_scanner_globals;
743743
#endif
744744

745-
#ifndef HAVE_FUNC_ATTRIBUTE_IFUNC
746745
zend_cpu_startup();
747-
#endif
748746

749747
#ifdef ZEND_WIN32
750748
php_win32_cp_set_by_id(65001);

Zend/zend_cpuinfo.c

-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
+----------------------------------------------------------------------+
1717
*/
1818

19-
#include "zend.h"
2019
#include "zend_cpuinfo.h"
2120

2221
typedef struct _zend_cpu_info {
@@ -68,10 +67,6 @@ void zend_cpu_startup(void)
6867
}
6968

7069
ZEND_API int zend_cpu_supports(zend_cpu_feature feature) {
71-
#ifdef HAVE_FUNC_ATTRIBUTE_IFUNC
72-
/* The resolver is invoked before zend_startup(). */
73-
zend_cpu_startup();
74-
#endif
7570
if (feature & ZEND_CPU_EDX_MASK) {
7671
return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK));
7772
} else {

Zend/zend_cpuinfo.h

+66-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#ifndef ZEND_CPU_INFO_H
2020
#define ZEND_CPU_INFO_H
2121

22+
#include "zend.h"
23+
2224
#define ZEND_CPU_EDX_MASK (1<<31)
2325

2426
typedef enum _zend_cpu_feature {
@@ -91,9 +93,72 @@ typedef enum _zend_cpu_feature {
9193
/*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/
9294
} zend_cpu_feature;
9395

96+
void zend_cpu_startup();
9497
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
9598

96-
void zend_cpu_startup(void);
99+
#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS
100+
/* NOTE: you should use following inline function in
101+
* resolver functions (ifunc), as it could be called
102+
* before all PLT symbols are resloved. in other words,
103+
* resolver functions should not depends any external
104+
* functions */
105+
static zend_always_inline int zend_cpu_support_sse2() {
106+
__builtin_cpu_init();
107+
return __builtin_cpu_supports("sse2");
108+
}
109+
110+
static zend_always_inline int zend_cpu_support_sse3() {
111+
__builtin_cpu_init();
112+
return __builtin_cpu_supports("sse3");
113+
}
114+
115+
static zend_always_inline int zend_cpu_support_sse41() {
116+
__builtin_cpu_init();
117+
return __builtin_cpu_supports("sse4.1");
118+
}
119+
120+
static zend_always_inline int zend_cpu_support_sse42() {
121+
__builtin_cpu_init();
122+
return __builtin_cpu_supports("sse4.2");
123+
}
124+
125+
static zend_always_inline int zend_cpu_support_avx() {
126+
__builtin_cpu_init();
127+
return __builtin_cpu_supports("avx");
128+
}
129+
130+
static zend_always_inline int zend_cpu_support_avx2() {
131+
__builtin_cpu_init();
132+
return __builtin_cpu_supports("avx2");
133+
}
134+
#else
135+
136+
static zend_always_inline int zend_cpu_support_sse2() {
137+
return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2);
138+
}
139+
140+
static zend_always_inline int zend_cpu_support_sse3() {
141+
return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3);
142+
}
143+
144+
static zend_always_inline int zend_cpu_support_sse41() {
145+
return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41);
146+
}
147+
148+
static zend_always_inline int zend_cpu_support_sse42() {
149+
return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42);
150+
}
151+
152+
static zend_always_inline int zend_cpu_support_avx() {
153+
return zend_cpu_supports(ZEND_CPU_FEATURE_AVX);
154+
}
155+
156+
static zend_always_inline int zend_cpu_support_avx2() {
157+
/* TODO */
158+
return 0;
159+
}
160+
161+
#endif
97162

98163
#endif
99164

acinclude.m4

+19
Original file line numberDiff line numberDiff line change
@@ -3241,6 +3241,25 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CPU_INIT], [
32413241
32423242
])
32433243

3244+
dnl PHP_CHECK_BUILTIN_CPU_SUPPORTS
3245+
AC_DEFUN([PHP_CHECK_BUILTIN_CPU_SUPPORTS], [
3246+
AC_MSG_CHECKING([for __builtin_cpu_supports])
3247+
3248+
AC_TRY_LINK(, [
3249+
return __builtin_cpu_supports("sse2")? 1 : 0;
3250+
], [
3251+
have_builtin_cpu_supports=1
3252+
AC_MSG_RESULT([yes])
3253+
], [
3254+
have_builtin_cpu_supports=0
3255+
AC_MSG_RESULT([no])
3256+
])
3257+
3258+
AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_CPU_SUPPORTS],
3259+
[$have_builtin_cpu_supports], [Whether the compiler supports __builtin_cpu_supports])
3260+
3261+
])
3262+
32443263
dnl Load the AX_CHECK_COMPILE_FLAG macro from the autoconf archive.
32453264
m4_include([build/ax_check_compile_flag.m4])
32463265

configure.ac

+2
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ dnl Check __builtin_ssubl_overflow
566566
PHP_CHECK_BUILTIN_SSUBL_OVERFLOW
567567
dnl Check __builtin_ssubll_overflow
568568
PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW
569+
dnl Check __builtin_cpu_supports
570+
PHP_CHECK_BUILTIN_CPU_SUPPORTS
569571

570572
dnl Check for members of the stat structure
571573
AC_STRUCT_ST_BLKSIZE

ext/standard/string.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3873,7 +3873,7 @@ zend_string *php_addslashes_default(zend_string *str, int should_free);
38733873
PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) __attribute__((ifunc("resolve_addslashes")));
38743874

38753875
static void *resolve_addslashes() {
3876-
if (zend_cpu_supports(ZEND_CPU_FEATURE_SSE42)) {
3876+
if (zend_cpu_support_sse42()) {
38773877
return php_addslashes_sse42;
38783878
}
38793879
return php_addslashes_default;

0 commit comments

Comments
 (0)