On Fri, Sep 12, 2025 at 11:09 PM Collin Funk <[email protected]> wrote:
>
> [...]
> Procfs isn't portable, and I don't think we could use CPU predefines.
> For example, compiling with the following:
>
> $ echo | gcc -mavx512f -dM -E - | grep AVX
> #define __AVX512F__ 1
>
> But my CPU doesn't support AVX512.
>
> [1]
> https://github.com/gcc-mirror/gcc/blob/908edc130910c5bea6d2d6b2a390793e7c106a6a/gcc/config/i386/i386-builtins.cc#L1334
Using __builtin_cpu_supports at runtime to check what the actual cpu
supports is portable.
-mavx512f says to enable AVX-512 extensions, so GCC enables it and
defines __AVX512F__. It is compile time, not runtime.
If you want to test what _your_ particular machine provides, use -march=native.
$ echo | gcc -march=native -dM -E - | grep -i -E '(SSE|AVX)'
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __MMX_WITH_SSE__ 1
#define __SSE2_MATH__ 1
#define __AVX__ 1
#define __SSE_MATH__ 1
#define __AVX2__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __AVXVNNI__ 1
#define __SSE2__ 1
#define __SSE3__ 1
But that is not portable. If you build a program, and I run it on my
old Dell laptop with SSE4.2, then the program will crash with a
SIGILL.
The sharp edge is, GCC and Clang make you use -mXXX to enable an
extension (otherwise you get a compile error), but then the compiler
starts generating its own code for that architecture without guarding
it via runtime checks, which [can] lead to SIGILL crashes. See, for
example, Restrict global constructors to base ISA,
<https://lists.llvm.org/pipermail/llvm-dev/2018-December/128159.html>.
Jeff