1 # Macros to detect C compiler features
5 # PGAC_PRINTF_ARCHETYPE
6 # ---------------------
7 # Select the format archetype to be used by gcc to check printf-type functions.
8 # We prefer "gnu_printf", as that most closely matches the features supported
9 # by src/port/snprintf.c (particularly the %m conversion spec). However,
10 # on some NetBSD versions, that doesn't work while "__syslog__" does.
11 # If all else fails, use "printf".
12 AC_DEFUN([PGAC_PRINTF_ARCHETYPE],
13 [AC_CACHE_CHECK([for printf format archetype], pgac_cv_printf_archetype,
14 [pgac_cv_printf_archetype=gnu_printf
15 PGAC_TEST_PRINTF_ARCHETYPE
16 if [[ "$ac_archetype_ok" = no ]]; then
17 pgac_cv_printf_archetype=__syslog__
18 PGAC_TEST_PRINTF_ARCHETYPE
19 if [[ "$ac_archetype_ok" = no ]]; then
20 pgac_cv_printf_archetype=printf
23 AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype],
24 [Define to best printf format archetype, usually gnu_printf if available.])
25 ])# PGAC_PRINTF_ARCHETYPE
27 # Subroutine: test $pgac_cv_printf_archetype, set $ac_archetype_ok to yes or no
28 AC_DEFUN([PGAC_TEST_PRINTF_ARCHETYPE],
29 [ac_save_c_werror_flag=$ac_c_werror_flag
31 AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
32 [extern void pgac_write(int ignore, const char *fmt,...)
33 __attribute__((format($pgac_cv_printf_archetype, 2, 3)));],
34 [pgac_write(0, "error %s: %m", "foo");])],
35 [ac_archetype_ok=yes],
37 ac_c_werror_flag=$ac_save_c_werror_flag
38 ])# PGAC_TEST_PRINTF_ARCHETYPE
41 # PGAC_TYPE_64BIT_INT(TYPE)
42 # -------------------------
43 # Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
44 # yes or no respectively, and define HAVE_TYPE_64 if yes.
45 AC_DEFUN([PGAC_TYPE_64BIT_INT],
46 [define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
47 define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
48 AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
49 [AC_RUN_IFELSE([AC_LANG_SOURCE(
53 * These are globals to discourage the compiler from folding all the
54 * arithmetic tests down to compile-time constants.
56 ac_int64 a = 20000001;
57 ac_int64 b = 40000005;
63 if (sizeof(ac_int64) != 8)
64 return 0; /* definitely not the right size */
66 /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
76 return (! does_int64_work());
80 [# If cross-compiling, check the size reported by the compiler and
81 # trust that the arithmetic works.
82 AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
86 Ac_define=$Ac_cachevar
87 if test x"$Ac_cachevar" = xyes ; then
88 AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
90 undefine([Ac_define])dnl
91 undefine([Ac_cachevar])dnl
92 ])# PGAC_TYPE_64BIT_INT
95 # PGAC_TYPE_128BIT_INT
96 # --------------------
97 # Check if __int128 is a working 128 bit integer type, and if so
98 # define PG_INT128_TYPE to that typename, and define ALIGNOF_PG_INT128_TYPE
99 # as its alignment requirement.
101 # This currently only detects a GCC/clang extension, but support for other
102 # environments may be added in the future.
104 # For the moment we only test for support for 128bit math; support for
105 # 128bit literals and snprintf is not required.
106 AC_DEFUN([PGAC_TYPE_128BIT_INT],
107 [AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int],
108 [AC_LINK_IFELSE([AC_LANG_PROGRAM([
110 * We don't actually run this test, just link it to verify that any support
111 * functions needed for __int128 are present.
113 * These are globals to discourage the compiler from folding all the
114 * arithmetic tests down to compile-time constants. We do not have
115 * convenient support for 128bit literals at this point...
117 __int128 a = 48828125;
118 __int128 b = 97656250;
121 a = (a << 12) + 1; /* 200000000001 */
122 b = (b << 12) + 5; /* 400000000005 */
123 /* try the most relevant arithmetic ops */
126 /* must use the results, else compiler may optimize arithmetic away */
130 [pgac_cv__128bit_int=yes],
131 [pgac_cv__128bit_int=no])])
132 if test x"$pgac_cv__128bit_int" = xyes ; then
133 # Use of non-default alignment with __int128 tickles bugs in some compilers.
134 # If not cross-compiling, we can test for bugs and disable use of __int128
135 # with buggy compilers. If cross-compiling, hope for the best.
136 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925
137 AC_CACHE_CHECK([for __int128 alignment bug], [pgac_cv__128bit_int_bug],
138 [AC_RUN_IFELSE([AC_LANG_PROGRAM([
139 /* This must match the corresponding code in c.h: */
140 #if defined(__GNUC__) || defined(__SUNPRO_C)
141 #define pg_attribute_aligned(a) __attribute__((aligned(a)))
142 #elif defined(_MSC_VER)
143 #define pg_attribute_aligned(a) __declspec(align(a))
145 typedef __int128 int128a
146 #if defined(pg_attribute_aligned)
147 pg_attribute_aligned(8)
151 void pass_by_val(void *buffer, int128a par) { holder = par; }
153 long int i64 = 97656225L << 12;
155 pass_by_val(main, (int128a) i64);
160 [pgac_cv__128bit_int_bug=ok],
161 [pgac_cv__128bit_int_bug=broken],
162 [pgac_cv__128bit_int_bug="assuming ok"])])
163 if test x"$pgac_cv__128bit_int_bug" != xbroken ; then
164 AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
165 AC_CHECK_ALIGNOF(PG_INT128_TYPE)
167 fi])# PGAC_TYPE_128BIT_INT
171 # PGAC_C_STATIC_ASSERT
172 # --------------------
173 # Check if the C compiler understands _Static_assert(),
174 # and define HAVE__STATIC_ASSERT if so.
176 # We actually check the syntax ({ _Static_assert(...) }), because we need
177 # gcc-style compound expressions to be able to wrap the thing into macros.
178 AC_DEFUN([PGAC_C_STATIC_ASSERT],
179 [AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert,
180 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
181 [({ _Static_assert(1, "foo"); })])],
182 [pgac_cv__static_assert=yes],
183 [pgac_cv__static_assert=no])])
184 if test x"$pgac_cv__static_assert" = xyes ; then
185 AC_DEFINE(HAVE__STATIC_ASSERT, 1,
186 [Define to 1 if your compiler understands _Static_assert.])
187 fi])# PGAC_C_STATIC_ASSERT
193 # Check if the C compiler understands typeof or a variant. Define
194 # HAVE_TYPEOF if so, and define 'typeof' to the actual key word.
196 AC_DEFUN([PGAC_C_TYPEOF],
197 [AC_CACHE_CHECK(for typeof, pgac_cv_c_typeof,
199 for pgac_kw in typeof __typeof__ decltype; do
200 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
205 [pgac_cv_c_typeof=$pgac_kw])
206 test "$pgac_cv_c_typeof" != no && break
208 if test "$pgac_cv_c_typeof" != no; then
209 AC_DEFINE(HAVE_TYPEOF, 1,
210 [Define to 1 if your compiler understands `typeof' or something similar.])
211 if test "$pgac_cv_c_typeof" != typeof; then
212 AC_DEFINE_UNQUOTED(typeof, $pgac_cv_c_typeof, [Define to how the compiler spells `typeof'.])
218 # PGAC_C_TYPES_COMPATIBLE
219 # -----------------------
220 # Check if the C compiler understands __builtin_types_compatible_p,
221 # and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so.
223 # We check usage with __typeof__, though it's unlikely any compiler would
224 # have the former and not the latter.
225 AC_DEFUN([PGAC_C_TYPES_COMPATIBLE],
226 [AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible,
227 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
228 [[ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ]])],
229 [pgac_cv__types_compatible=yes],
230 [pgac_cv__types_compatible=no])])
231 if test x"$pgac_cv__types_compatible" = xyes ; then
232 AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
233 [Define to 1 if your compiler understands __builtin_types_compatible_p.])
234 fi])# PGAC_C_TYPES_COMPATIBLE
237 # PGAC_C_BUILTIN_CONSTANT_P
238 # -------------------------
239 # Check if the C compiler understands __builtin_constant_p(),
240 # and define HAVE__BUILTIN_CONSTANT_P if so.
241 # We need __builtin_constant_p("string literal") to be true, but some older
242 # compilers don't think that, so test for that case explicitly.
243 AC_DEFUN([PGAC_C_BUILTIN_CONSTANT_P],
244 [AC_CACHE_CHECK(for __builtin_constant_p, pgac_cv__builtin_constant_p,
245 [AC_COMPILE_IFELSE([AC_LANG_SOURCE(
247 static int y[__builtin_constant_p(x) ? x : 1];
248 static int z[__builtin_constant_p("string literal") ? 1 : x];
251 [pgac_cv__builtin_constant_p=yes],
252 [pgac_cv__builtin_constant_p=no])])
253 if test x"$pgac_cv__builtin_constant_p" = xyes ; then
254 AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1,
255 [Define to 1 if your compiler understands __builtin_constant_p.])
256 fi])# PGAC_C_BUILTIN_CONSTANT_P
260 # PGAC_C_BUILTIN_OP_OVERFLOW
261 # --------------------------
262 # Check if the C compiler understands __builtin_$op_overflow(),
263 # and define HAVE__BUILTIN_OP_OVERFLOW if so.
265 # Check for the most complicated case, 64 bit multiplication, as a
266 # proxy for all of the operations. To detect the case where the compiler
267 # knows the function but library support is missing, we must link not just
268 # compile, and store the results in global variables so the compiler doesn't
269 # optimize away the call.
270 AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW],
271 [AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow,
272 [AC_LINK_IFELSE([AC_LANG_PROGRAM([
275 PG_INT64_TYPE result;
278 [oflo = __builtin_mul_overflow(a, b, &result);])],
279 [pgac_cv__builtin_op_overflow=yes],
280 [pgac_cv__builtin_op_overflow=no])])
281 if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
282 AC_DEFINE(HAVE__BUILTIN_OP_OVERFLOW, 1,
283 [Define to 1 if your compiler understands __builtin_$op_overflow.])
284 fi])# PGAC_C_BUILTIN_OP_OVERFLOW
288 # PGAC_C_BUILTIN_UNREACHABLE
289 # --------------------------
290 # Check if the C compiler understands __builtin_unreachable(),
291 # and define HAVE__BUILTIN_UNREACHABLE if so.
293 # NB: Don't get the idea of putting a for(;;); or such before the
294 # __builtin_unreachable() call. Some compilers would remove it before linking
295 # and only a warning instead of an error would be produced.
296 AC_DEFUN([PGAC_C_BUILTIN_UNREACHABLE],
297 [AC_CACHE_CHECK(for __builtin_unreachable, pgac_cv__builtin_unreachable,
298 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
299 [__builtin_unreachable();])],
300 [pgac_cv__builtin_unreachable=yes],
301 [pgac_cv__builtin_unreachable=no])])
302 if test x"$pgac_cv__builtin_unreachable" = xyes ; then
303 AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1,
304 [Define to 1 if your compiler understands __builtin_unreachable.])
305 fi])# PGAC_C_BUILTIN_UNREACHABLE
309 # PGAC_C_COMPUTED_GOTO
310 # --------------------
311 # Check if the C compiler knows computed gotos (gcc extension, also
312 # available in at least clang). If so, define HAVE_COMPUTED_GOTO.
314 # Checking whether computed gotos are supported syntax-wise ought to
315 # be enough, as the syntax is otherwise illegal.
316 AC_DEFUN([PGAC_C_COMPUTED_GOTO],
317 [AC_CACHE_CHECK(for computed goto support, pgac_cv_computed_goto,
318 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
319 [[void *labeladdrs[] = {&&my_label};
324 [pgac_cv_computed_goto=yes],
325 [pgac_cv_computed_goto=no])])
326 if test x"$pgac_cv_computed_goto" = xyes ; then
327 AC_DEFINE(HAVE_COMPUTED_GOTO, 1,
328 [Define to 1 if your compiler handles computed gotos.])
329 fi])# PGAC_C_COMPUTED_GOTO
333 # PGAC_CHECK_BUILTIN_FUNC
334 # -----------------------
335 # This is similar to AC_CHECK_FUNCS(), except that it will work for compiler
336 # builtin functions, as that usually fails to.
337 # The first argument is the function name, eg [__builtin_clzl], and the
338 # second is its argument list, eg [unsigned long x]. The current coding
339 # works only for a single argument named x; we might generalize that later.
340 # It's assumed that the function's result type is coercible to int.
341 # On success, we define "HAVEfuncname" (there's usually more than enough
342 # underscores already, so we don't add another one).
343 AC_DEFUN([PGAC_CHECK_BUILTIN_FUNC],
344 [AC_CACHE_CHECK(for $1, pgac_cv$1,
345 [AC_LINK_IFELSE([AC_LANG_PROGRAM([
353 if test x"${pgac_cv$1}" = xyes ; then
354 AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE$1]), 1,
355 [Define to 1 if your compiler understands $1.])
356 fi])# PGAC_CHECK_BUILTIN_FUNC
360 # PGAC_CHECK_BUILTIN_FUNC_PTR
361 # -----------------------
362 # Like PGAC_CHECK_BUILTIN_FUNC, except that the function is assumed to
363 # return a pointer type, and the argument(s) should be given literally.
364 # This handles some cases that PGAC_CHECK_BUILTIN_FUNC doesn't.
365 AC_DEFUN([PGAC_CHECK_BUILTIN_FUNC_PTR],
366 [AC_CACHE_CHECK(for $1, pgac_cv$1,
367 [AC_LINK_IFELSE([AC_LANG_PROGRAM([
375 if test x"${pgac_cv$1}" = xyes ; then
376 AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE$1]), 1,
377 [Define to 1 if your compiler understands $1.])
378 fi])# PGAC_CHECK_BUILTIN_FUNC_PTR
382 # PGAC_PROG_VARCC_VARFLAGS_OPT
383 # ----------------------------
384 # Given a compiler, variable name and a string, check if the compiler
385 # supports the string as a command-line option. If it does, add the
386 # string to the given variable.
387 AC_DEFUN([PGAC_PROG_VARCC_VARFLAGS_OPT],
388 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cflags_$3])])dnl
389 AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar],
390 [pgac_save_CFLAGS=$CFLAGS
394 ac_save_c_werror_flag=$ac_c_werror_flag
396 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
399 ac_c_werror_flag=$ac_save_c_werror_flag
400 CFLAGS="$pgac_save_CFLAGS"
402 if test x"$Ac_cachevar" = x"yes"; then
405 undefine([Ac_cachevar])dnl
406 ])# PGAC_PROG_VARCC_VARFLAGS_OPT
410 # PGAC_PROG_CC_CFLAGS_OPT
411 # -----------------------
412 # Given a string, check if the compiler supports the string as a
413 # command-line option. If it does, add the string to CFLAGS.
414 AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT], [
415 PGAC_PROG_VARCC_VARFLAGS_OPT(CC, CFLAGS, $1)
416 ])# PGAC_PROG_CC_CFLAGS_OPT
420 # PGAC_PROG_CC_VAR_OPT
421 # --------------------
422 # Given a variable name and a string, check if the compiler supports
423 # the string as a command-line option. If it does, add the string to
424 # the given variable.
425 AC_DEFUN([PGAC_PROG_CC_VAR_OPT],
426 [PGAC_PROG_VARCC_VARFLAGS_OPT(CC, $1, $2)
427 ])# PGAC_PROG_CC_VAR_OPT
431 # PGAC_PROG_VARCXX_VARFLAGS_OPT
432 # -----------------------------
433 # Given a compiler, variable name and a string, check if the compiler
434 # supports the string as a command-line option. If it does, add the
435 # string to the given variable.
436 AC_DEFUN([PGAC_PROG_VARCXX_VARFLAGS_OPT],
437 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cxxflags_$3])])dnl
438 AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar],
439 [pgac_save_CXXFLAGS=$CXXFLAGS
443 ac_save_cxx_werror_flag=$ac_cxx_werror_flag
444 ac_cxx_werror_flag=yes
446 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
450 ac_cxx_werror_flag=$ac_save_cxx_werror_flag
451 CXXFLAGS="$pgac_save_CXXFLAGS"
452 CXX="$pgac_save_CXX"])
453 if test x"$Ac_cachevar" = x"yes"; then
456 undefine([Ac_cachevar])dnl
457 ])# PGAC_PROG_VARCXX_VARFLAGS_OPT
461 # PGAC_PROG_CXX_CFLAGS_OPT
462 # ------------------------
463 # Given a string, check if the compiler supports the string as a
464 # command-line option. If it does, add the string to CXXFLAGS.
465 AC_DEFUN([PGAC_PROG_CXX_CFLAGS_OPT],
466 [PGAC_PROG_VARCXX_VARFLAGS_OPT(CXX, CXXFLAGS, $1)
467 ])# PGAC_PROG_CXX_CFLAGS_OPT
471 # PGAC_PROG_CC_LD_VARFLAGS_OPT
472 # ------------------------
473 # Given a string, check if the compiler supports the string as a
474 # command-line option. If it does, add to the given variable.
475 # For reasons you'd really rather not know about, this checks whether
476 # you can link to a particular function, not just whether you can link.
477 # In fact, we must actually check that the resulting program runs :-(
478 AC_DEFUN([PGAC_PROG_CC_LD_VARFLAGS_OPT],
479 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_$1_$2])])dnl
480 AC_CACHE_CHECK([whether $CC supports $2, for $1], [Ac_cachevar],
481 [pgac_save_LDFLAGS=$LDFLAGS
482 LDFLAGS="$pgac_save_LDFLAGS $2"
483 AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $3 (); void (*fptr) () = $3;],[])],
486 [Ac_cachevar="assuming no"])
487 LDFLAGS="$pgac_save_LDFLAGS"])
488 if test x"$Ac_cachevar" = x"yes"; then
491 undefine([Ac_cachevar])dnl
492 ])# PGAC_PROG_CC_LD_VARFLAGS_OPT
494 # PGAC_PROG_CC_LDFLAGS_OPT
495 # ------------------------
496 # Convenience wrapper around PGAC_PROG_CC_LD_VARFLAGS_OPT that adds to
498 AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
499 [PGAC_PROG_CC_LD_VARFLAGS_OPT(LDFLAGS, [$1], [$2])
500 ])# PGAC_PROG_CC_LDFLAGS_OPT
503 # PGAC_HAVE_GCC__SYNC_CHAR_TAS
504 # ----------------------------
505 # Check if the C compiler understands __sync_lock_test_and_set(char),
506 # and define HAVE_GCC__SYNC_CHAR_TAS
508 # NB: There are platforms where test_and_set is available but compare_and_swap
509 # is not, so test this separately.
510 # NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both.
511 AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS],
512 [AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas,
513 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
515 __sync_lock_test_and_set(&lock, 1);
516 __sync_lock_release(&lock);])],
517 [pgac_cv_gcc_sync_char_tas="yes"],
518 [pgac_cv_gcc_sync_char_tas="no"])])
519 if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then
520 AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.])
521 fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS
523 # PGAC_HAVE_GCC__SYNC_INT32_TAS
524 # -----------------------------
525 # Check if the C compiler understands __sync_lock_test_and_set(),
526 # and define HAVE_GCC__SYNC_INT32_TAS
527 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS],
528 [AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas,
529 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
531 __sync_lock_test_and_set(&lock, 1);
532 __sync_lock_release(&lock);])],
533 [pgac_cv_gcc_sync_int32_tas="yes"],
534 [pgac_cv_gcc_sync_int32_tas="no"])])
535 if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then
536 AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
537 fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS
539 # PGAC_HAVE_GCC__SYNC_INT32_CAS
540 # -----------------------------
541 # Check if the C compiler understands __sync_compare_and_swap() for 32bit
542 # types, and define HAVE_GCC__SYNC_INT32_CAS if so.
543 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS],
544 [AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas,
545 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
547 __sync_val_compare_and_swap(&val, 0, 37);])],
548 [pgac_cv_gcc_sync_int32_cas="yes"],
549 [pgac_cv_gcc_sync_int32_cas="no"])])
550 if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then
551 AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int *, int, int).])
552 fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
554 # PGAC_HAVE_GCC__SYNC_INT64_CAS
555 # -----------------------------
556 # Check if the C compiler understands __sync_compare_and_swap() for 64bit
557 # types, and define HAVE_GCC__SYNC_INT64_CAS if so.
558 AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
559 [AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
560 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
561 [PG_INT64_TYPE lock = 0;
562 __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
563 [pgac_cv_gcc_sync_int64_cas="yes"],
564 [pgac_cv_gcc_sync_int64_cas="no"])])
565 if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
566 AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).])
567 fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
569 # PGAC_HAVE_GCC__ATOMIC_INT32_CAS
570 # -------------------------------
571 # Check if the C compiler understands __atomic_compare_exchange_n() for 32bit
572 # types, and define HAVE_GCC__ATOMIC_INT32_CAS if so.
573 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS],
574 [AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas,
575 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
578 __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
579 [pgac_cv_gcc_atomic_int32_cas="yes"],
580 [pgac_cv_gcc_atomic_int32_cas="no"])])
581 if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then
582 AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).])
583 fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
585 # PGAC_HAVE_GCC__ATOMIC_INT64_CAS
586 # -------------------------------
587 # Check if the C compiler understands __atomic_compare_exchange_n() for 64bit
588 # types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
589 AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
590 [AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
591 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
592 [PG_INT64_TYPE val = 0;
593 PG_INT64_TYPE expect = 0;
594 __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
595 [pgac_cv_gcc_atomic_int64_cas="yes"],
596 [pgac_cv_gcc_atomic_int64_cas="no"])])
597 if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then
598 AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, int64).])
599 fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
601 # PGAC_SSE42_CRC32_INTRINSICS
602 # ---------------------------
603 # Check if the compiler supports the x86 CRC instructions added in SSE 4.2,
604 # using the _mm_crc32_u8 and _mm_crc32_u32 intrinsic functions. (We don't
605 # test the 8-byte variant, _mm_crc32_u64, but it is assumed to be present if
606 # the other ones are, on x86-64 platforms)
608 # An optional compiler flag can be passed as argument (e.g. -msse4.2). If the
609 # intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_CRC.
610 AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS],
611 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl
612 AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar],
613 [pgac_save_CFLAGS=$CFLAGS
614 CFLAGS="$pgac_save_CFLAGS $1"
615 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <nmmintrin.h>],
616 [unsigned int crc = 0;
617 crc = _mm_crc32_u8(crc, 0);
618 crc = _mm_crc32_u32(crc, 0);
619 /* return computed value, to prevent the above being optimized away */
623 CFLAGS="$pgac_save_CFLAGS"])
624 if test x"$Ac_cachevar" = x"yes"; then
626 pgac_sse42_crc32_intrinsics=yes
628 undefine([Ac_cachevar])dnl
629 ])# PGAC_SSE42_CRC32_INTRINSICS
632 # PGAC_ARMV8_CRC32C_INTRINSICS
633 # ----------------------------
634 # Check if the compiler supports the CRC32C instructions using the __crc32cb,
635 # __crc32ch, __crc32cw, and __crc32cd intrinsic functions. These instructions
636 # were first introduced in ARMv8 in the optional CRC Extension, and became
637 # mandatory in ARMv8.1.
639 # An optional compiler flag can be passed as argument (e.g.
640 # -march=armv8-a+crc). If the intrinsics are supported, sets
641 # pgac_armv8_crc32c_intrinsics, and CFLAGS_CRC.
642 AC_DEFUN([PGAC_ARMV8_CRC32C_INTRINSICS],
643 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_armv8_crc32c_intrinsics_$1])])dnl
644 AC_CACHE_CHECK([for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=$1], [Ac_cachevar],
645 [pgac_save_CFLAGS=$CFLAGS
646 CFLAGS="$pgac_save_CFLAGS $1"
647 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <arm_acle.h>],
648 [unsigned int crc = 0;
649 crc = __crc32cb(crc, 0);
650 crc = __crc32ch(crc, 0);
651 crc = __crc32cw(crc, 0);
652 crc = __crc32cd(crc, 0);
653 /* return computed value, to prevent the above being optimized away */
657 CFLAGS="$pgac_save_CFLAGS"])
658 if test x"$Ac_cachevar" = x"yes"; then
660 pgac_armv8_crc32c_intrinsics=yes
662 undefine([Ac_cachevar])dnl
663 ])# PGAC_ARMV8_CRC32C_INTRINSICS
665 # PGAC_LOONGARCH_CRC32C_INTRINSICS
666 # ---------------------------
667 # Check if the compiler supports the LoongArch CRCC instructions, using
668 # __builtin_loongarch_crcc_w_b_w, __builtin_loongarch_crcc_w_h_w,
669 # __builtin_loongarch_crcc_w_w_w and __builtin_loongarch_crcc_w_d_w
670 # intrinsic functions.
672 # We test for the 8-byte variant since platforms capable of running
673 # Postgres are 64-bit only (as of PG17), and we know CRC instructions
674 # are available there without a runtime check.
676 # If the intrinsics are supported, sets pgac_loongarch_crc32c_intrinsics.
677 AC_DEFUN([PGAC_LOONGARCH_CRC32C_INTRINSICS],
678 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_loongarch_crc32c_intrinsics])])dnl
680 [for __builtin_loongarch_crcc_w_b_w, __builtin_loongarch_crcc_w_h_w, __builtin_loongarch_crcc_w_w_w and __builtin_loongarch_crcc_w_d_w],
682 [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
683 [unsigned int crc = 0;
684 crc = __builtin_loongarch_crcc_w_b_w(0, crc);
685 crc = __builtin_loongarch_crcc_w_h_w(0, crc);
686 crc = __builtin_loongarch_crcc_w_w_w(0, crc);
687 crc = __builtin_loongarch_crcc_w_d_w(0, crc);
688 /* return computed value, to prevent the above being optimized away */
692 if test x"$Ac_cachevar" = x"yes"; then
693 pgac_loongarch_crc32c_intrinsics=yes
695 undefine([Ac_cachevar])dnl
696 ])# PGAC_LOONGARCH_CRC32C_INTRINSICS
698 # PGAC_XSAVE_INTRINSICS
699 # ---------------------
700 # Check if the compiler supports the XSAVE instructions using the _xgetbv
701 # intrinsic function.
703 # An optional compiler flag can be passed as argument (e.g., -mxsave). If the
704 # intrinsic is supported, sets pgac_xsave_intrinsics and CFLAGS_XSAVE.
705 AC_DEFUN([PGAC_XSAVE_INTRINSICS],
706 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_xsave_intrinsics_$1])])dnl
707 AC_CACHE_CHECK([for _xgetbv with CFLAGS=$1], [Ac_cachevar],
708 [pgac_save_CFLAGS=$CFLAGS
709 CFLAGS="$pgac_save_CFLAGS $1"
710 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>],
711 [return _xgetbv(0) & 0xe0;])],
714 CFLAGS="$pgac_save_CFLAGS"])
715 if test x"$Ac_cachevar" = x"yes"; then
717 pgac_xsave_intrinsics=yes
719 undefine([Ac_cachevar])dnl
720 ])# PGAC_XSAVE_INTRINSICS
722 # PGAC_AVX512_POPCNT_INTRINSICS
723 # -----------------------------
724 # Check if the compiler supports the AVX-512 popcount instructions using the
725 # _mm512_setzero_si512, _mm512_maskz_loadu_epi8, _mm512_popcnt_epi64,
726 # _mm512_add_epi64, and _mm512_reduce_add_epi64 intrinsic functions.
728 # Optional compiler flags can be passed as argument (e.g., -mavx512vpopcntdq
729 # -mavx512bw). If the intrinsics are supported, sets
730 # pgac_avx512_popcnt_intrinsics and CFLAGS_POPCNT.
731 AC_DEFUN([PGAC_AVX512_POPCNT_INTRINSICS],
732 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_avx512_popcnt_intrinsics_$1])])dnl
733 AC_CACHE_CHECK([for _mm512_popcnt_epi64 with CFLAGS=$1], [Ac_cachevar],
734 [pgac_save_CFLAGS=$CFLAGS
735 CFLAGS="$pgac_save_CFLAGS $1"
736 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>],
737 [const char buf@<:@sizeof(__m512i)@:>@;
738 PG_INT64_TYPE popcnt = 0;
739 __m512i accum = _mm512_setzero_si512();
740 const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
741 const __m512i cnt = _mm512_popcnt_epi64(val);
742 accum = _mm512_add_epi64(accum, cnt);
743 popcnt = _mm512_reduce_add_epi64(accum);
744 /* return computed value, to prevent the above being optimized away */
745 return popcnt == 0;])],
748 CFLAGS="$pgac_save_CFLAGS"])
749 if test x"$Ac_cachevar" = x"yes"; then
751 pgac_avx512_popcnt_intrinsics=yes
753 undefine([Ac_cachevar])dnl
754 ])# PGAC_AVX512_POPCNT_INTRINSICS