From 39b3a0abf937320458c84005a7faed0fd005e5d7 Mon Sep 17 00:00:00 2001 From: Lukas Fittl Date: Sat, 31 Jan 2026 08:49:46 -0800 Subject: [PATCH v4 1/3] Check for HAVE__CPUIDEX and HAVE__GET_CPUID_COUNT separately Previously we would only check for the availability of __cpuidex if the related __get_cpuid_count was not available on a platform. But there are cases where we want to be able to call __cpuidex as the only viable option, specifically, when accessing a high leaf like VM Hypervisor information (0x40000000), which __get_cpuid_count does not allow. This will be used in an future commit to access Hypervisor information about the TSC frequency of x86 CPUs, where available. Note that __cpuidex is defined in cpuid.h for GCC/clang, but in intrin.h for MSVC. Because we now set HAVE__CPUIDEX for GCC/clang when available, adjust existing code to check for _MSC_VER when including intrin.h. --- configure | 20 ++++++++++++-------- configure.ac | 30 +++++++++++++++++------------- meson.build | 10 ++++++++-- src/port/pg_crc32c_sse42_choose.c | 4 ++-- src/port/pg_popcount_x86.c | 4 ++-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/configure b/configure index a10a2c85c6a..38de88fcc50 100755 --- a/configure +++ b/configure @@ -17648,7 +17648,8 @@ $as_echo "#define HAVE__CPUID 1" >>confdefs.h fi fi -# Check for __get_cpuid_count() and __cpuidex() in a similar fashion. +# Check for __get_cpuid_count() and __cpuidex() separately, since we sometimes +# need __cpuidex() even if __get_cpuid_count() is available. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __get_cpuid_count" >&5 $as_echo_n "checking for __get_cpuid_count... " >&6; } if ${pgac_cv__get_cpuid_count+:} false; then : @@ -17681,21 +17682,25 @@ if test x"$pgac_cv__get_cpuid_count" = x"yes"; then $as_echo "#define HAVE__GET_CPUID_COUNT 1" >>confdefs.h -else - # __cpuidex() - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpuidex" >&5 +fi +# __cpuidex() +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpuidex" >&5 $as_echo_n "checking for __cpuidex... " >&6; } if ${pgac_cv__cpuidex+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#ifdef _MSC_VER + #include + #else + #include + #endif int main () { unsigned int exx[4] = {0, 0, 0, 0}; - __cpuidex(exx, 7, 0); + __cpuidex(exx, 7, 0); ; return 0; @@ -17711,11 +17716,10 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__cpuidex" >&5 $as_echo "$pgac_cv__cpuidex" >&6; } - if test x"$pgac_cv__cpuidex" = x"yes"; then +if test x"$pgac_cv__cpuidex" = x"yes"; then $as_echo "#define HAVE__CPUIDEX 1" >>confdefs.h - fi fi # Check for XSAVE intrinsics diff --git a/configure.ac b/configure.ac index 814e64a967e..6e174cba328 100644 --- a/configure.ac +++ b/configure.ac @@ -2098,7 +2098,8 @@ else fi fi -# Check for __get_cpuid_count() and __cpuidex() in a similar fashion. +# Check for __get_cpuid_count() and __cpuidex() separately, since we sometimes +# need __cpuidex() even if __get_cpuid_count() is available. AC_CACHE_CHECK([for __get_cpuid_count], [pgac_cv__get_cpuid_count], [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [[unsigned int exx[4] = {0, 0, 0, 0}; @@ -2108,18 +2109,21 @@ AC_CACHE_CHECK([for __get_cpuid_count], [pgac_cv__get_cpuid_count], [pgac_cv__get_cpuid_count="no"])]) if test x"$pgac_cv__get_cpuid_count" = x"yes"; then AC_DEFINE(HAVE__GET_CPUID_COUNT, 1, [Define to 1 if you have __get_cpuid_count.]) -else - # __cpuidex() - AC_CACHE_CHECK([for __cpuidex], [pgac_cv__cpuidex], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [[unsigned int exx[4] = {0, 0, 0, 0}; - __cpuidex(exx, 7, 0); - ]])], - [pgac_cv__cpuidex="yes"], - [pgac_cv__cpuidex="no"])]) - if test x"$pgac_cv__cpuidex" = x"yes"; then - AC_DEFINE(HAVE__CPUIDEX, 1, [Define to 1 if you have __cpuidex.]) - fi +fi +# __cpuidex() +AC_CACHE_CHECK([for __cpuidex], [pgac_cv__cpuidex], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([#ifdef _MSC_VER + #include + #else + #include + #endif], + [[unsigned int exx[4] = {0, 0, 0, 0}; + __cpuidex(exx, 7, 0); + ]])], + [pgac_cv__cpuidex="yes"], + [pgac_cv__cpuidex="no"])]) +if test x"$pgac_cv__cpuidex" = x"yes"; then + AC_DEFINE(HAVE__CPUIDEX, 1, [Define to 1 if you have __cpuidex.]) fi # Check for XSAVE intrinsics diff --git a/meson.build b/meson.build index df907b62da3..2b106135869 100644 --- a/meson.build +++ b/meson.build @@ -2078,7 +2078,8 @@ elif cc.links(''' endif -# Check for __get_cpuid_count() and __cpuidex() in a similar fashion. +# Check for __get_cpuid_count() and __cpuidex() separately, since we sometimes +# need __cpuidex() even if __get_cpuid_count() is available. if cc.links(''' #include int main(int arg, char **argv) @@ -2089,8 +2090,13 @@ if cc.links(''' ''', name: '__get_cpuid_count', args: test_c_args) cdata.set('HAVE__GET_CPUID_COUNT', 1) -elif cc.links(''' +endif +if cc.links(''' + #ifdef _MSC_VER #include + #else + #include + #endif int main(int arg, char **argv) { unsigned int exx[4] = {0, 0, 0, 0}; diff --git a/src/port/pg_crc32c_sse42_choose.c b/src/port/pg_crc32c_sse42_choose.c index f586476964f..7a75380b483 100644 --- a/src/port/pg_crc32c_sse42_choose.c +++ b/src/port/pg_crc32c_sse42_choose.c @@ -20,11 +20,11 @@ #include "c.h" -#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT) +#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT) || (defined(HAVE__CPUIDEX) && !defined(_MSC_VER)) #include #endif -#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX) +#if defined(HAVE__CPUID) || (defined(HAVE__CPUIDEX) && defined(_MSC_VER)) #include #endif diff --git a/src/port/pg_popcount_x86.c b/src/port/pg_popcount_x86.c index 245f0167d00..f8a20766f2d 100644 --- a/src/port/pg_popcount_x86.c +++ b/src/port/pg_popcount_x86.c @@ -14,7 +14,7 @@ #ifdef HAVE_X86_64_POPCNTQ -#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT) +#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT) || (defined(HAVE__CPUIDEX) && !defined(_MSC_VER)) #include #endif @@ -22,7 +22,7 @@ #include #endif -#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX) +#if defined(HAVE__CPUID) || (defined(HAVE__CPUIDEX) && defined(_MSC_VER)) #include #endif -- 2.47.1