Does Clang have something like #pragma GCC target?

You should probably be using static inline instead of inline, so a version of a function compiled with -mavx will only be used by callers from that translation unit.

The linker will still merge actual duplicates, instead of just picking one non-inline definition by name.

This also has the advantage that the compiler doesn't waste time emitting a stand-alone definition for functions that it decides to inline into every caller in that translation unit.


The gcc/clang way makes sense if you're used to it and design your code for it. And note that MSVC need AVX enabled if you're compiling functions that use AVX. Otherwise it will mix VEX and non-VEX encodings, leading to big penalties, instead of using the VEX encoding for something like a 128-bit _mm_add_ps in a horizontal add at the end of a _mm256_add_ps loop.

So you basically have the same problem with MSVC, that compiling _mm_whatever will make AVX-only machine code.


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.