Search code examples
clangintrinsicsavxpragma

Does Clang have something like #pragma GCC target?


I have some code written that uses AVX intrinsics when they are available on the current CPU. In GCC and Clang, unlike Visual C++, in order to use intrinsics, you must enable them on the command line.

The problem with GCC and Clang is that when you enable these options, you're giving the compiler free reign to use those instructions everywhere in your source file. This is very bad when you have header files containing inline functions or template functions, because the compiler will generate these functions with AVX instructions.

When linking, duplicate functions will be discarded. However, because some source files were compiled with -mavx and some were not, the various compilations of the inline/template functions will be different. If you're unlucky, the linker will randomly choose the version that has AVX instructions, causing the program to crash when run on a system without AVX.

GCC solves this with #pragma GCC target. You can turn off the special instructions for the header files, and the code generated will not use AVX:

#pragma GCC push_options
#pragma GCC target("no-avx")

#include "MyHeader.h"

#pragma GCC pop_options

Does Clang have anything like this? It seems to ignore these options and generates AVX code anyway.


Solution

  • The Clang equivalent to GCC push_options / GCC target / GCC pop_options are the clang attribute push / clang attribute pop pragmas along with the target attribute:

    #pragma clang attribute push (__attribute__((target("pclmul,sse4.1,ssse3"))), apply_to=function)
    // ...
    #pragma clang attribute pop
    

    This is the equivalent of:

    #pragma GCC push_options
    #pragma GCC target("pclmul", "sse4.1", "ssse3")
    // ...
    #pragma GCC pop_options
    

    Note that where the GCC target pragma takes a comma-delimited list of target options, the clang target attribute takes a single string, comma-delimited internally.

    Clang supports negative target options (such as "no-avx"), but I prefer to use positive options to add to the feature set selected by command line options.