]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
build: fix od build on clang < 17
authorPádraig Brady <P@draigBrady.com>
Wed, 7 Feb 2024 10:55:00 +0000 (10:55 +0000)
committerPádraig Brady <P@draigBrady.com>
Wed, 7 Feb 2024 11:13:38 +0000 (11:13 +0000)
* 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
src/od.c
tests/od/od-float.sh

index 64ff32a96ff491acd1c23a3d3731b43b661aef64..c7eca1b8d51339933636d3aa9f634ee6f3a68ab9 100644 (file)
@@ -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"
index 1e24893671e5454f85edc19c7e8e4dc1f72a243d..d23df2c5e132ebb166b70ebddf068e8115573992 100644 (file)
--- 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;
index 239b5f10e4710e2371fef8132dff7d42a5bb3257..d9aab26b7b144d470926815c5043f349cc9070e5 100755 (executable)
@@ -17,7 +17,7 @@
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 . "${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