Detecting support for __fp16

1.6k Views Asked by At

Since version 6, clang has supported a __fp16 type. I would like to use it, but I need to support other compilers (both clang-based and non-clang-based) as well as older versions of clang, so I need a reliable way to detect support. Unfortunately, I don't see anything in clang's documentation about how to detect it (using __has_feature, __has_extension, etc.).

Since clang's version number macros are unreliable, the best solution I have right now is to use __has_warning("-Wpragma-pack") (the -Wpragma-pack warning was also added in clang 6). I'm hoping that there is a fp16 feature/extension/whatever I can check instead which just isn't documented where I'm looking, but obviously open to other ideas.

So, does anyone know of a better way to detect __fp16 support?

2

There are 2 best solutions below

0
On

I need a reliable way to detect support

The reliable way to detect support for compiler constructs is to compile an example program that uses that construct. This has been achieved since forever with build systems, for example in CMake with try_compile or AC_COMPILE_IFELSE in autoconf.

0
On

So, the solution to this required digging into the LLVM C++ v1 __config header for the magic incantation.

// CAUTION: __is_identifier behaves opposite how you would expect!
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
// the compiler and '1' otherwise.
// borrowed from LLVM __config header under Apache license 2. 
// (https://www.mend.io/blog/top-10-apache-license-questions-answered/)
#ifndef __is_identifier         // Optional of course.
  #define __is_identifier(x) 1  // Compatibility with non-clang compilers.
#endif

// More sensible macro for keyword detection
#  define __has_keyword(__x) !(__is_identifier(__x))

// map a half float type, if available, to _OptionalHalfFloatType
#if __has_keyword(_Float16)
    typedef _Float16    _OptionalHalfFloatType;
#elif __has_keyword(__fp16)
    typedef __fp16      _OptionalHalfFloatType;
#else
    typedef void        _OptionalHalfFloatType;
#endif