postgres.git / summary / log / commit / refs

commit    7ca388fd0decece896518f61fb5e4c0648690deb
Author:   Thomas Munro <tmunro@postgresql.org>
Date:     Fri Nov 22 01:53:21 2024 +0000
First released in: 18.0, 13.19, 14.16, 15.11, 16.7, 17.3

    jit: Use -mno-outline-atomics for bitcode on ARM.
    
    If the executable's .o files were produced by a compiler (probably gcc)
    not using -moutline-atomics, and the corresponding .bc files were
    produced by clang using -moutline-atomics (probably by default), then
    the generated bitcode functions would have the target attribute
    "+outline-atomics", and could fail at runtime when inlined.  If the
    target ISA at bitcode generation time was armv8-a (the most conservative
    aarch64 target, no LSE), then LLVM IR atomic instructions would generate
    calls to functions in libgcc.a or libclang_rt.*.a that switch between
    LL/SC and faster LSE instructions depending on a runtime AT_HWCAP check.
    Since the corresponding .o files didn't need those functions, they
    wouldn't have been included in the executable, and resolution would
    fail.
    
    At least Debian and Ubuntu are known to ship gcc and clang compilers
    that target armv8-a but differ on the use of outline atomics by default.
    
    Fix, by suppressing the outline atomics attribute in bitcode explicitly.
    Inline LL/SC instructions will be generated for atomic operations in
    bitcode built for armv8-a.  Only configure scripts are adjusted for now,
    because the meson build system doesn't generate bitcode yet.
    
    This doesn't seem to be a new phenomenon, so real cases of functions
    using atomics that are inlined by JIT must be rare in the wild given how
    long it took for a bug report to arrive.  The reported case could be
    reduced to:
    
    postgres=# set jit_inline_above_cost = 0;
    SET
    postgres=# set jit_above_cost = 0;
    SET
    postgres=# select pg_last_wal_receive_lsn();
    WARNING:  failed to resolve name __aarch64_swp4_acq_rel
    FATAL:  fatal llvm error: Program used external function
    '__aarch64_swp4_acq_rel' which could not be resolved!
    
    The change doesn't affect non-ARM systems or later target ISAs.
    
    Back-patch to all supported releases.
    
    Reported-by: Alexander Kozhemyakin <a.kozhemyakin@postgrespro.ru>
    Discussion: https://postgr.es/m/18610-37bf303f904fede3%40postgresql.org


configure | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 7 ++++ 2 files changed, 112 insertions(+) diff --git a/configure b/configure index 7e6030e9e18..e4f1fc92ab3 100755 --- a/configure +++ b/configure @@ -7394,6 +7394,111 @@ if test x"$pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers" = x"yes"; fi + # Ideally bitcode should perhaps match $CC's use, or not, of outline atomic + # functions, but for now we err on the side of suppressing them in bitcode, + # because we can't assume they're available at runtime. This affects aarch64 + # builds using the basic armv8-a ISA without LSE support. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -mno-outline-atomics, for BITCODE_CFLAGS" >&5 +$as_echo_n "checking whether ${CLANG} supports -mno-outline-atomics, for BITCODE_CFLAGS... " >&6; } +if ${pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CLANG} +CXXFLAGS="${BITCODE_CFLAGS} -mno-outline-atomics" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics=yes +else + pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" >&5 +$as_echo "$pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" >&6; } +if test x"$pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" = x"yes"; then + BITCODE_CFLAGS="${BITCODE_CFLAGS} -mno-outline-atomics" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -mno-outline-atomics, for BITCODE_CXXFLAGS" >&5 +$as_echo_n "checking whether ${CLANG} supports -mno-outline-atomics, for BITCODE_CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CLANG} +CXXFLAGS="${BITCODE_CXXFLAGS} -mno-outline-atomics" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics=yes +else + pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" >&5 +$as_echo "$pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" >&6; } +if test x"$pgac_cv_prog_CLANG_cxxflags__mno_outline_atomics" = x"yes"; then + BITCODE_CXXFLAGS="${BITCODE_CXXFLAGS} -mno-outline-atomics" +fi + + NOT_THE_CFLAGS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS" >&5 $as_echo_n "checking whether ${CLANG} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS... " >&6; } diff --git a/configure.ac b/configure.ac index 7a75d6e37c3..d6563a194e5 100644 --- a/configure.ac +++ b/configure.ac @@ -609,6 +609,13 @@ if test "$with_llvm" = yes ; then PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-Xclang -no-opaque-pointers]) PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANGXX, BITCODE_CXXFLAGS, [-Xclang -no-opaque-pointers]) + # Ideally bitcode should perhaps match $CC's use, or not, of outline atomic + # functions, but for now we err on the side of suppressing them in bitcode, + # because we can't assume they're available at runtime. This affects aarch64 + # builds using the basic armv8-a ISA without LSE support. + PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-mno-outline-atomics]) + PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANG, BITCODE_CXXFLAGS, [-mno-outline-atomics]) + NOT_THE_CFLAGS="" PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, NOT_THE_CFLAGS, [-Wunused-command-line-argument]) if test -n "$NOT_THE_CFLAGS"; then [parent: 1c5fe56bc259]