Header files for x86 SIMD intrinsics

The header name depends on your compiler and target architecture.

  • For Microsoft C++ (targeting x86, x86-64 or ARM) and Intel C/C++ Compiler for Windows use intrin.h
  • For gcc/clang/icc targeting x86/x86-64 use x86intrin.h
  • For gcc/clang/armcc targeting ARM with NEON use arm_neon.h
  • For gcc/clang/armcc targeting ARM with WMMX use mmintrin.h
  • For gcc/clang/xlcc targeting PowerPC with VMX (aka Altivec) and/or VSX use altivec.h
  • For gcc/clang targeting PowerPC with SPE use spe.h

You can handle all these cases with conditional preprocessing directives:

#if defined(_MSC_VER)
     /* Microsoft C/C++-compatible compiler */
     #include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
     /* GCC-compatible compiler, targeting x86/x86-64 */
     #include <x86intrin.h>
#elif defined(__GNUC__) && defined(__ARM_NEON__)
     /* GCC-compatible compiler, targeting ARM with NEON */
     #include <arm_neon.h>
#elif defined(__GNUC__) && defined(__IWMMXT__)
     /* GCC-compatible compiler, targeting ARM with WMMX */
     #include <mmintrin.h>
#elif (defined(__GNUC__) || defined(__xlC__)) && (defined(__VEC__) || defined(__ALTIVEC__))
     /* XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX */
     #include <altivec.h>
#elif defined(__GNUC__) && defined(__SPE__)
     /* GCC-compatible compiler, targeting PowerPC with SPE */
     #include <spe.h>
#endif

These days you should normally just include <immintrin.h>. It includes everything.

GCC and clang will stop you from using intrinsics for instructions you haven't enabled at compile time (e.g. with -march=native or -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1 or whatever.)

MSVC and ICC will let you use intrinsics without enabling anything at compile time, but you still should enable AVX before using AVX intrinsics.


Historically (before immintrin.h pulled in everything) you had to manually include a header for the highest level of intrinsics you wanted.

This may still be useful with MSVC and ICC to stop yourself from using instruction-sets you don't want to require.

<mmintrin.h>  MMX
<xmmintrin.h> SSE
<emmintrin.h> SSE2
<pmmintrin.h> SSE3
<tmmintrin.h> SSSE3
<smmintrin.h> SSE4.1
<nmmintrin.h> SSE4.2
<ammintrin.h> SSE4A
<wmmintrin.h> AES
<immintrin.h> AVX, AVX2, FMA

Including one of these pulls in all previous ones (except AMD-only SSE4A: immintrin.h doesn't pull that in)

Some compilers also have <zmmintrin.h> for AVX512.


On GCC/clang, if you use just

#include <x86intrin.h>

it will include all SSE/AVX headers which are enabled according to compiler switches like -march=haswell or just -march=native. Additionally some x86 specific instructions like bswap or ror become available as intrinsics.


The MSVC equivalent of this header <intrin.h>


If you just want portable SIMD, use #include <immintrin.h>

MSVC, ICC, and gcc/clang (and other compilers like Sun I think) all support this header for the SIMD intrinsics documented by Intel's only intrinsics finder / search tool: https://software.intel.com/sites/landingpage/IntrinsicsGuide/