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.