Doc: update src/tools/pgindent/README for current practice.
[pgsql.git] / config / c-compiler.m4
blob10f8c7bd0a9fbb12a2e7c0060560fe385dd9d01b
1 # Macros to detect C compiler features
2 # config/c-compiler.m4
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
21   fi
22 fi])
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
30 ac_c_werror_flag=yes
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],
36                   [ac_archetype_ok=no])
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(
50 [typedef $1 ac_int64;
53  * These are globals to discourage the compiler from folding all the
54  * arithmetic tests down to compile-time constants.
55  */
56 ac_int64 a = 20000001;
57 ac_int64 b = 40000005;
59 int does_int64_work()
61   ac_int64 c,d;
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 */
67   c = a * b;
68   d = (c + b) / b;
69   if (d != a+1)
70     return 0;
71   return 1;
74 int
75 main() {
76   return (! does_int64_work());
77 }])],
78 [Ac_cachevar=yes],
79 [Ac_cachevar=no],
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])],
83                   Ac_cachevar=yes,
84                   Ac_cachevar=no)])])
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...
116  */
117 __int128 a = 48828125;
118 __int128 b = 97656250;
120 __int128 c,d;
121 a = (a << 12) + 1; /* 200000000001 */
122 b = (b << 12) + 5; /* 400000000005 */
123 /* try the most relevant arithmetic ops */
124 c = a * b;
125 d = (c + b) / b;
126 /* must use the results, else compiler may optimize arithmetic away */
127 if (d != a+1)
128   return 1;
129 ])],
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))
144 #endif
145 typedef __int128 int128a
146 #if defined(pg_attribute_aligned)
147 pg_attribute_aligned(8)
148 #endif
150 int128a holder;
151 void pass_by_val(void *buffer, int128a par) { holder = par; }
153 long int i64 = 97656225L << 12;
154 int128a q;
155 pass_by_val(main, (int128a) i64);
156 q = (int128a) i64;
157 if (q != holder)
158   return 1;
159 ])],
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)
166   fi
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
191 # PGAC_C_TYPEOF
192 # -------------
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,
198 [pgac_cv_c_typeof=no
199 for pgac_kw in typeof __typeof__ decltype; do
200   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
201 [int x = 0;
202 $pgac_kw(x) y;
203 y = x;
204 return y;])],
205 [pgac_cv_c_typeof=$pgac_kw])
206   test "$pgac_cv_c_typeof" != no && break
207 done])
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'.])
213   fi
214 fi])# PGAC_C_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(
246 [[static int x;
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([
273 PG_INT64_TYPE a = 1;
274 PG_INT64_TYPE b = 1;
275 PG_INT64_TYPE result;
276 int oflo;
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};
320   goto *labeladdrs[0];
321   my_label:
322   return 1;
323 ]])],
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([
347 call$1($2)
349     return $1(x);
350 }], [])],
351 [pgac_cv$1=yes],
352 [pgac_cv$1=no])])
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([
368 void *
369 call$1(void)
371     return $1($2);
372 }], [])],
373 [pgac_cv$1=yes],
374 [pgac_cv$1=no])])
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
391 pgac_save_CC=$CC
392 CC=${$1}
393 CFLAGS="${$2} $3"
394 ac_save_c_werror_flag=$ac_c_werror_flag
395 ac_c_werror_flag=yes
396 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
397                    [Ac_cachevar=yes],
398                    [Ac_cachevar=no])
399 ac_c_werror_flag=$ac_save_c_werror_flag
400 CFLAGS="$pgac_save_CFLAGS"
401 CC="$pgac_save_CC"])
402 if test x"$Ac_cachevar" = x"yes"; then
403   $2="${$2} $3"
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
440 pgac_save_CXX=$CXX
441 CXX=${$1}
442 CXXFLAGS="${$2} $3"
443 ac_save_cxx_werror_flag=$ac_cxx_werror_flag
444 ac_cxx_werror_flag=yes
445 AC_LANG_PUSH(C++)
446 _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
447                    [Ac_cachevar=yes],
448                    [Ac_cachevar=no])
449 AC_LANG_POP([])
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
454   $2="${$2} $3"
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;],[])],
484               [Ac_cachevar=yes],
485               [Ac_cachevar=no],
486               [Ac_cachevar="assuming no"])
487 LDFLAGS="$pgac_save_LDFLAGS"])
488 if test x"$Ac_cachevar" = x"yes"; then
489   $1="${$1} $2"
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
497 # LDFLAGS.
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([],
514   [char lock = 0;
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([],
530   [int lock = 0;
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([],
546   [int val = 0;
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([],
576   [int val = 0;
577    int expect = 0;
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 */
620    return crc == 0;])],
621   [Ac_cachevar=yes],
622   [Ac_cachevar=no])
623 CFLAGS="$pgac_save_CFLAGS"])
624 if test x"$Ac_cachevar" = x"yes"; then
625   CFLAGS_CRC="$1"
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 */
654    return crc == 0;])],
655   [Ac_cachevar=yes],
656   [Ac_cachevar=no])
657 CFLAGS="$pgac_save_CFLAGS"])
658 if test x"$Ac_cachevar" = x"yes"; then
659   CFLAGS_CRC="$1"
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
679 AC_CACHE_CHECK(
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],
681   [Ac_cachevar],
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 */
689    return crc == 0;])],
690   [Ac_cachevar=yes],
691   [Ac_cachevar=no])])
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;])],
712   [Ac_cachevar=yes],
713   [Ac_cachevar=no])
714 CFLAGS="$pgac_save_CFLAGS"])
715 if test x"$Ac_cachevar" = x"yes"; then
716   CFLAGS_XSAVE="$1"
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;])],
746   [Ac_cachevar=yes],
747   [Ac_cachevar=no])
748 CFLAGS="$pgac_save_CFLAGS"])
749 if test x"$Ac_cachevar" = x"yes"; then
750   CFLAGS_POPCNT="$1"
751   pgac_avx512_popcnt_intrinsics=yes
753 undefine([Ac_cachevar])dnl
754 ])# PGAC_AVX512_POPCNT_INTRINSICS