From f85472082c5920951a2886c114612c5002899fb8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Wed, 7 Feb 2024 10:55:00 +0000 Subject: [PATCH] build: fix od build on clang < 17 * configure.ac: Ensure the compiler can promote 16 bit floating point types to float, before enabling that code in od. This was an issue with clang 16 at least. * src/od.c: Adjust for the new defines. * tests/od/od-float.sh: Likewise. Also port to the dash shell, whose inbuilt printf doesn't support hex escapes. --- configure.ac | 40 +++++++++++++++++++++++++++++++++++++++- src/od.c | 20 ++++++++++---------- tests/od/od-float.sh | 10 +++++----- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 64ff32a96..c7eca1b8d 100644 --- a/configure.ac +++ b/configure.ac @@ -523,7 +523,45 @@ LDFLAGS=$ac_save_LDFLAGS ac_c_werror_flag=$cu_save_c_werror_flag # Test compiler support for half precision floating point types (for od) -AC_CHECK_TYPES([_Float16, __bf16]) +AC_MSG_CHECKING([IEEE 16 bit floating point]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + int + main (void) + { + _Float16 hf; + float f = hf; /* Ensure compiler can promote to float. */ + } + ]]) + ],[ + ieee_16_bit_supported=yes + ],[ + ieee_16_bit_supported=no + ]) +AC_MSG_RESULT([$ieee_16_bit_supported]) +if test $ieee_16_bit_supported = yes; then + AC_DEFINE([FLOAT16_SUPPORTED], [1], [IEEE 16 bit float supported]) +fi + +AC_MSG_CHECKING([Brain 16 bit floating point]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + int + main (void) + { + __bf16 hf; + float f = hf; /* Ensure compiler can promote to float. */ + } + ]]) + ],[ + brain_16_bit_supported=yes + ],[ + brain_16_bit_supported=no + ]) +AC_MSG_RESULT([$brain_16_bit_supported]) +if test $brain_16_bit_supported = yes; then + AC_DEFINE([BF16_SUPPORTED], [1], [Brain 16 bit float supported]) +fi ac_save_CFLAGS=$CFLAGS CFLAGS="-mavx -mpclmul $CFLAGS" diff --git a/src/od.c b/src/od.c index 1e2489367..d23df2c5e 100644 --- a/src/od.c +++ b/src/od.c @@ -50,21 +50,21 @@ typedef unsigned long long int unsigned_long_long_int; typedef unsigned long int unsigned_long_long_int; #endif -#if HAVE__FLOAT16 +#if FLOAT16_SUPPORTED /* Available since clang 6 (2018), and gcc 7 (2017). */ typedef _Float16 float16; #else -# define HAVE__FLOAT16 0 +# define FLOAT16_SUPPORTED 0 /* This is just a place-holder to avoid a few '#if' directives. In this case, the type isn't actually used. */ typedef float float16; #endif -#if HAVE___BF16 +#if BF16_SUPPORTED /* Available since clang 11 (2020), and gcc 13 (2023). */ typedef __bf16 bfloat16; #else -# define HAVE___BF16 0 +# define BF16_SUPPORTED 0 /* This is just a place-holder to avoid a few '#if' directives. In this case, the type isn't actually used. */ typedef float bfloat16; @@ -180,7 +180,7 @@ static const int width_bytes[] = sizeof (int), sizeof (long int), sizeof (unsigned_long_long_int), -#if HAVE___BF16 +#if BF16_SUPPORTED sizeof (bfloat16), #else sizeof (float16), @@ -847,7 +847,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next, { if (size > MAX_FP_TYPE_SIZE || fp_type_size[size] == NO_SIZE - || (! HAVE__FLOAT16 && HAVE___BF16 + || (! FLOAT16_SUPPORTED && BF16_SUPPORTED && size == sizeof (bfloat16)) ) { @@ -864,8 +864,8 @@ decode_one_format (char const *s_orig, char const *s, char const **next, } size_spec = fp_type_size[size]; - if ((! HAVE__FLOAT16 && fmt == HFLOATING_POINT) - || (! HAVE___BF16 && fmt == BFLOATING_POINT)) + if ((! FLOAT16_SUPPORTED && fmt == HFLOATING_POINT) + || (! BF16_SUPPORTED && fmt == BFLOATING_POINT)) { error (0, 0, _("this system doesn't provide a %s floating point type"), @@ -1660,9 +1660,9 @@ main (int argc, char **argv) for (i = 0; i <= MAX_FP_TYPE_SIZE; i++) fp_type_size[i] = NO_SIZE; -#if HAVE__FLOAT16 +#if FLOAT16_SUPPORTED fp_type_size[sizeof (float16)] = FLOAT_HALF; -#elif HAVE___BF16 +#elif BF16_SUPPORTED fp_type_size[sizeof (bfloat16)] = FLOAT_HALF; #endif fp_type_size[sizeof (float)] = FLOAT_SINGLE; diff --git a/tests/od/od-float.sh b/tests/od/od-float.sh index 239b5f10e..d9aab26b7 100755 --- a/tests/od/od-float.sh +++ b/tests/od/od-float.sh @@ -17,7 +17,7 @@ # along with this program. If not, see . . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -print_ver_ od +print_ver_ od printf export LC_ALL=C @@ -70,9 +70,9 @@ set x $(printf 00000000ff000000 | tr 0f '\000\377' | od -t fL) || fail=1 #esac # Check Half precision IEEE 16 bit float -if grep '^#define HAVE__FLOAT16 1' "$CONFIG_HEADER" >/dev/null; then +if grep '^#define FLOAT16_SUPPORTED 1' "$CONFIG_HEADER" >/dev/null; then for fmt in '-tfH' '-tf2'; do - od_out=$(printf '\x3C\x00\x3C\x00' | od --endian=big -An $fmt | tr -d ' ') + od_out=$(env printf '\x3C\x00\x3C\x00' | od --end=big -An $fmt | tr -d ' ') test "$od_out" = '11' || fail=1 done else @@ -81,8 +81,8 @@ else compare exp_err err || fail=1 fi # Check Half precision Brain 16 bit float -if grep '^#define HAVE___BF16 1' "$CONFIG_HEADER" >/dev/null; then - od_out=$(printf '\x3F\x80\x3F\x80' | od --endian=big -An -tfB | tr -d ' ') +if grep '^#define BF16_SUPPORTED 1' "$CONFIG_HEADER" >/dev/null; then + od_out=$(env printf '\x3F\x80\x3F\x80' | od --end=big -An -tfB | tr -d ' ') test "$od_out" = '11' || fail=1 else echo "od: this system doesn't provide a 'fB' floating point type" > exp_err -- 2.11.4.GIT