Fix mis-deparsing of ORDER BY lists when there is a name conflict.
[pgsql.git] / src / port / pg_popcount_avx512_choose.c
blobb37107803a8c32e8ce6cbbaeee0439e6c1330066
1 /*-------------------------------------------------------------------------
3 * pg_popcount_avx512_choose.c
4 * Test whether we can use the AVX-512 pg_popcount() implementation.
6 * Copyright (c) 2024, PostgreSQL Global Development Group
8 * IDENTIFICATION
9 * src/port/pg_popcount_avx512_choose.c
11 *-------------------------------------------------------------------------
13 #include "c.h"
15 #if defined(HAVE__GET_CPUID) || defined(HAVE__GET_CPUID_COUNT)
16 #include <cpuid.h>
17 #endif
19 #ifdef HAVE_XSAVE_INTRINSICS
20 #include <immintrin.h>
21 #endif
23 #if defined(HAVE__CPUID) || defined(HAVE__CPUIDEX)
24 #include <intrin.h>
25 #endif
27 #include "port/pg_bitutils.h"
30 * It's probably unlikely that TRY_POPCNT_FAST won't be set if we are able to
31 * use AVX-512 intrinsics, but we check it anyway to be sure. We piggy-back on
32 * the function pointers that are only used when TRY_POPCNT_FAST is set.
34 #ifdef TRY_POPCNT_FAST
37 * Does CPUID say there's support for XSAVE instructions?
39 static inline bool
40 xsave_available(void)
42 unsigned int exx[4] = {0, 0, 0, 0};
44 #if defined(HAVE__GET_CPUID)
45 __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
46 #elif defined(HAVE__CPUID)
47 __cpuid(exx, 1);
48 #else
49 #error cpuid instruction not available
50 #endif
51 return (exx[2] & (1 << 27)) != 0; /* osxsave */
55 * Does XGETBV say the ZMM registers are enabled?
57 * NB: Caller is responsible for verifying that xsave_available() returns true
58 * before calling this.
60 static inline bool
61 zmm_regs_available(void)
63 #ifdef HAVE_XSAVE_INTRINSICS
64 return (_xgetbv(0) & 0xe6) == 0xe6;
65 #else
66 return false;
67 #endif
71 * Does CPUID say there's support for AVX-512 popcount and byte-and-word
72 * instructions?
74 static inline bool
75 avx512_popcnt_available(void)
77 unsigned int exx[4] = {0, 0, 0, 0};
79 #if defined(HAVE__GET_CPUID_COUNT)
80 __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]);
81 #elif defined(HAVE__CPUIDEX)
82 __cpuidex(exx, 7, 0);
83 #else
84 #error cpuid instruction not available
85 #endif
86 return (exx[2] & (1 << 14)) != 0 && /* avx512-vpopcntdq */
87 (exx[1] & (1 << 30)) != 0; /* avx512-bw */
91 * Returns true if the CPU supports the instructions required for the AVX-512
92 * pg_popcount() implementation.
94 bool
95 pg_popcount_avx512_available(void)
97 return xsave_available() &&
98 zmm_regs_available() &&
99 avx512_popcnt_available();
102 #endif /* TRY_POPCNT_FAST */