Check for __cpuidex and __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.

Future commits will need to access hypervisor information about
the TSC frequency of x86 CPUs. For that case __cpuidex is the only
viable option for accessing a high leaf (e.g. 0x40000000), since
__get_cpuid_count does not allow that.

__cpuidex is defined in cpuid.h for gcc/clang, but in intrin.h
for MSVC, so adjust tests to suite. We also need to cast the array
of unsigned ints to signed, since gcc (with -Wall) and clang emit
warnings otherwise.

Author: Lukas Fittl <lukas@fittl.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: John Naylor <john.naylor@postgresql.org>
Discussion: https://postgr.es/m/CAP53PkyooCeR8YV0BUD_xC7oTZESHz8OdA=tP7pBRHFVQ9xtKg@mail.gmail.com
This commit is contained in:
John Naylor 2026-04-02 19:39:57 +07:00
parent bb6ae9707c
commit effaa464af
4 changed files with 42 additions and 29 deletions

20
configure vendored
View file

@ -17746,7 +17746,7 @@ $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()
{ $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 :
@ -17779,21 +17779,26 @@ 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
# Check for __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 <intrin.h>
#ifdef _MSC_VER
#include <intrin.h>
#else
#include <cpuid.h>
#endif
int
main ()
{
unsigned int exx[4] = {0, 0, 0, 0};
__cpuidex(exx, 7, 0);
__cpuidex((int *) exx, 7, 0);
;
return 0;
@ -17809,11 +17814,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

View file

@ -2107,7 +2107,7 @@ else
fi
fi
# Check for __get_cpuid_count() and __cpuidex() in a similar fashion.
# Check for __get_cpuid_count()
AC_CACHE_CHECK([for __get_cpuid_count], [pgac_cv__get_cpuid_count],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <cpuid.h>],
[[unsigned int exx[4] = {0, 0, 0, 0};
@ -2117,18 +2117,22 @@ 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 <intrin.h>],
[[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
# Check for __cpuidex()
AC_CACHE_CHECK([for __cpuidex], [pgac_cv__cpuidex],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#ifdef _MSC_VER
#include <intrin.h>
#else
#include <cpuid.h>
#endif],
[[unsigned int exx[4] = {0, 0, 0, 0};
__cpuidex((int *) 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

View file

@ -2132,7 +2132,7 @@ elif cc.links('''
endif
# Check for __get_cpuid_count() and __cpuidex() in a similar fashion.
# Check for __get_cpuid_count()
if cc.links('''
#include <cpuid.h>
int main(int arg, char **argv)
@ -2143,12 +2143,19 @@ if cc.links('''
''', name: '__get_cpuid_count',
args: test_c_args)
cdata.set('HAVE__GET_CPUID_COUNT', 1)
elif cc.links('''
endif
# Check for __cpuidex()
if cc.links('''
#ifdef _MSC_VER
#include <intrin.h>
#else
#include <cpuid.h>
#endif
int main(int arg, char **argv)
{
unsigned int exx[4] = {0, 0, 0, 0};
__cpuidex(exx, 7, 0);
__cpuidex((int *) exx, 7, 0);
}
''', name: '__cpuidex',
args: test_c_args)

View file

@ -17,12 +17,10 @@
#if defined(USE_SSE2) || defined(__i386__)
#if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
#include <cpuid.h>
#endif
#if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
#ifdef _MSC_VER
#include <intrin.h>
#else
#include <cpuid.h>
#endif
#ifdef HAVE_XSAVE_INTRINSICS