[cfe-dev] Should _has_builtin be aware of target features?
Akira Hatanaka via cfe-dev
cfe-dev at lists.llvm.org
Tue Jan 19 12:30:58 PST 2016
ping.
How about defining a new builtin (__builtin_has_builtin?) that evaluates to
true of false at compile time based on the target features set by both the
command line options and target attributes on the function?
For example, clang's code-gen will not emit IR for the else statement in
the following piece of code if the builtin evaluates to true:
if (__builtin_has_builtin("somebuiltin")) {
// use "somebuiltin"
} else {
...
}
On Mon, Nov 2, 2015 at 3:55 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:
> _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/20160119/36d0db4e/attachment.html>
More information about the cfe-dev
mailing list