Subject: bug#69770: [PATCH] build: strengthen 16 bit float support checks

From: Pádraig Brady <[email-masked]>
Date: Fri, 15 Mar 2024 11:49:26 +0000

On 15/03/2024 05:21, Paul Eggert wrote:
> On 2024-03-14 06:03, Pádraig Brady wrote:
>>
>>> How about leaving it AC_COMPILE_IFELSE, but ensuring that -O1 or better
>>> is used when the compiler supports -O1? That way we don't have to worry
>>> about running the program, because (with the "volatile") clang will
>>> error out.
>>>
>>> Alternatively perhaps there's some way to check for the bug using
>>> preprocessor macros like __FLT16_MANT_DIG__, __FLT16_MAX_EXP__,
>>> __clang_major__, and __aarch64__. (This could be more fragile, though,
>>> as clang presumably will fix the bug eventually.)
>>
>> That would probably work for this edge case, but it's brittle
>> and I'm worried about other combinations of
>> compiler versions, complier options, and architectures.
> 
> Sure, but one cannot resolve such worries completely, as compiler errors
> are inherently brittle: even a runtime test cannot prove their absence.
> 
> As I understand it, __bf16 is a real zoo: sometimes hardware supports
> it, sometimes it doesn't, sometimes the software emulation library is
> there, sometimes it's not, and so forth. Running a program on a
> development host is likely to not match the runtime behavior on a
> production host, so AC_RUN_IFELSE is reasonably likely to produce a
> false positive, which is worse than a false negative.
> 
> Another issue, which is somewhat related, is that coreutils's current
> macro BF16_SUPPORTED is too broad. Because __bf16 has so many bugs,
> currently it's probably a mistake to say __bf16 is fully supported
> anywhere. Even GCC is buggy; see for example:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114347
> 
> which I just now discovered when writing this email.

Nice one! (though that should not impact od)

> The question isn't
> so much whether __bf16 is supported, it's whether it's supported well
> enough to compile and run GNU od. >
> 
> Come to think of it, for 'od' we might be better off avoiding __bf16
> entirely, and simply converting the bits by hand into a 'float'
> variable. This would likely be more portable, as it would work even with
> compilers that lack __bf16, or that have __bf16 bugs relevant to 'od'.
> And that way we could remove the configure-time test entirely. (There
> would be endianness issues but they're easily addressible.)

Right.

My thinking though was that it was nice code wise to treat __bf16 like
_Float16 (and like float etc.).
More importantly I only see __bf16 support improving going forward,
so preferred to keep the code simpler (and the configure check robust).
Currently both the main compilers, and main architectures are supported
(when not cross-compiling), and tested quite robustly in the configure check.
Another thing that dissuaded me from implementing the conversions ourselves
is the plethora of floating point config options for compilers,
which made me think in general that floating point conversion
was best left to the compiler.

I've just now realized that AC_RUN_IFELSE needs an explicit default
for cross-compiling, and I've just pushed a conservative default
(which may default the other way in future when support broadens).

thanks,
Pádraig.