Skip to content

Commit

Permalink
opal_config_asm: strengthen the __atomic_compare_exchange_n() test
Browse files Browse the repository at this point in the history
Per lengthy discussion on open-mpi#5529
and open-mpi#5546, it seems that -- at
least as of August 2018 -- on ARM64+clang, the
__atomic_compare_exchange_n() intrinsic function does exist, but it
does not behave the way that Open MPI expects it to.  Strengthen our
configure test to make sure that the function not only exists, but
also behaves the way Open MPI expects it to.

Many thanks to Stefan Teleman for the bug report.

Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
  • Loading branch information
jsquyres committed Aug 16, 2018
1 parent 3f69c40 commit 0f493aa
Showing 1 changed file with 67 additions and 7 deletions.
74 changes: 67 additions & 7 deletions config/opal_config_asm.m4
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,71 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
atomic_compare_exchange_n_128_result=0
# This is a C test to see if 128-bit __atomic_compare_exchange_n()
# actually works (e.g., it compiles and links successfully on
# ARM64+clang, but returns incorrect answers as of August 2018).
file=conftest.$$.c
rm -f $file
cat > $file <<EOF
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
typedef union {
uint64_t fake[2];
__int128 real;
} ompi128;
static void test1(void)
{
// As of Aug 2018, we could not figure out a way to assign 128-bit
// constants -- the compilers would not accept it. So use a fake
// union to assign 2 uin64_t's to make a since __int128.
ompi128 ptr = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
ompi128 expected = { .fake = { 0x11EEDDCCBBAA0099, 0x88776655443322FF }};
ompi128 desired = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
bool r = __atomic_compare_exchange_n (&ptr.real,
&expected.real,
desired.real,
true,
__ATOMIC_RELAXED,
__ATOMIC_RELAXED);
if (!(r == false && ptr.real == expected.real)) {
exit(1);
}
}
static void test2(void)
{
ompi128 ptr = (ompi128) { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
ompi128 expected = ptr;
ompi128 desired = (ompi128) { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
bool r = __atomic_compare_exchange_n (&ptr.real,
&expected.real,
desired.real,
true,
__ATOMIC_RELAXED,
__ATOMIC_RELAXED);
if (!(r == true && ptr.real == desired.real)) {
exit(1);
}
}
int main(int argc, char** argv[])
{
test1();
test2();
return 0;
}
EOF
if test ! "$enable_cross_cmpset128" = "yes" ; then
# Do this test if we can AC RUN_IFELSE (i.e., if we are not
# cross-compiling).
AC_MSG_CHECKING([for processor support of __atomic builtin atomic compare-and-swap on 128-bit values])
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);])],
AC_RUN_IFELSE([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1],
[AC_MSG_RESULT([no])],
Expand All @@ -176,7 +235,7 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
CFLAGS="$CFLAGS -mcx16"
AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -mcx16 flag])
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);])],
AC_RUN_IFELSE([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1
CFLAGS_save="$CFLAGS"],
Expand All @@ -191,7 +250,7 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
LDFLAGS="$LDFLAGS -latomic"
AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -latomic])
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);])],
AC_RUN_IFELSE([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1
LDFLAGS_save="$LDFLAGS"],
Expand Down Expand Up @@ -225,7 +284,7 @@ dnl before going into OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128
AC_MSG_CHECKING([for compiler support of __atomic builtin atomic compare-and-swap on 128-bit values])
# Check if the compiler supports the __atomic builtin
AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);],
AC_TRY_LINK([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1],
[AC_MSG_RESULT([no])])
Expand All @@ -235,7 +294,7 @@ dnl before going into OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128
CFLAGS="$CFLAGS -mcx16"
AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -mcx16 flag])
AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);],
AC_TRY_LINK([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1
CFLAGS_save="$CFLAGS"],
Expand All @@ -249,17 +308,18 @@ dnl before going into OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128
LDFLAGS="$LDFLAGS -latomic"
AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -latomic])
AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);],
AC_TRY_LINK([AC_LANG_SOURCE([`cat $file`])],
[AC_MSG_RESULT([yes])
atomic_compare_exchange_n_128_result=1
LDFLAGS_save="$LDFLAGS"],
[AC_MSG_RESULT([no])])
LDFLAGS=$LDFLAGS_save
fi
fi
AS_IF([test -r $file], [rm -f $file])
AC_DEFINE_UNQUOTED([OPAL_HAVE_GCC_BUILTIN_CSWAP_INT128], [$atomic_compare_exchange_n_128_result],
[Whether the __atomic builtin atomic compare and swap is lock-free on 128-bit values])
Expand Down

0 comments on commit 0f493aa

Please sign in to comment.