[cfe-dev] Should _has_builtin be aware of target features?

Akira Hatanaka via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 2 15:55:57 PST 2015


_has_builtin is a function-like macro that evaluates to 1 if the builtin
function name that's passed to it is supported by the current version of
clang or the architecture that is being targeted.

http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros

Some people have expressed interest in enhancing the functionality of this
macro and making it aware of target features.

For example, let's say I had the following program and wanted to emit avx2
 builtin __builtin_ia32_paddsw256 if the target architecture supported it
and emit a plain addition if it was unsupported (I don't know whether the
users will specify -mavx2 on the command line):

$ cat add1.c

typedef unsigned short v16hi __attribute__((__vector_size__(32)));

v16hi func1(v16hi a, v16hi b) {
#if __has_builtin(__builtin_ia32_paddsw256)
  return __builtin_ia32_paddsw256(a, b);
#else
  return a + b;
#endif
}

Currently, clang fails to compile this program unless -mavx2 is explicitly
specified on the command line or the target supports avx2:

$ clang add1.c -S -o - -v -emit-llvm

*add1.c:5:10: **error: **'__builtin_ia32_paddsw256' needs target feature
avx2*

  return __builtin_ia32_paddsw256(a, b);

This happens because _has_builtin always evaluates to 1 if the current
version of clang supports the builtin for the target architecture (x86 in
the case above) regardless of which target features (e.g., avx2) are set.
So in this case, we want _has_builtin to know which features are set and
evaluate to 0 if feature avx2 is not set.

However, making _has_builitin smarter breaks the following use case:

$ cat add1.c
v16hi __attribute__((target("avx2"))) func1(v16hi a, v16hi b) {
#if __has_builtin(__builtin_ia32_paddsw256)
  return __builtin_ia32_paddsw256(a, b);
#else
  return a + b;
#endif
}

$ clang add1.c -S -o - -v -emit-llvm

If a user compiles the program with clang today, __has_builtin returns 1
because the builtin is supported. In this case, this is what the user
wants: the user doesn't need to know if avx2 instructions are available
(the target attribute says avx2 is available) but just wants to use
_has_builitin to find out whether the current version of clang supports the
builtin. However, if we make _has_builtin aware of the target feature,
__has_builtin will evaluate to 0, which results in clang emitting the plain
addition instead of the builtin (note that the preprocessor is not aware of
what target attributes are on the function).

I can see how making _has_builtin aware of target features can improve
programmers' experience. But I've also heard opinions from people who are
concerned about the use cases this change will break, so I'm sending out
this email to a wider audience.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151102/598fab7f/attachment.html>


More information about the cfe-dev mailing list