Reputation: 102205
I'm trying to create a minimal reproducer for this issue report. There seems to be some problems with AVX-512, which is shipping on the latest Apple machines with Skylake processors.
According to GCC6 release notes the AVX-512 gear should be available. According to the Intel Intrinsics Guide vmovdqu64
is available with AVX-512VL
and AVX-512F
:
$ cat test.cxx
#include <cstdint>
#include <immintrin.h>
int main(int argc, char* argv[])
{
uint64_t x[8];
__m512i y = _mm512_loadu_epi64(x);
return 0;
}
And then:
$ /opt/local/bin/g++-mp-6 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
$ /opt/local/bin/g++-mp-6 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
$ /opt/local/bin/g++-mp-6 -msse4.1 -msse4.2 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
I walked the options back to -msse2
without success. I seem to be missing something.
What is required to engage AVX-512 for modern GCC?
According to a /opt/local/bin/g++-mp-6 -v
, these are the header search paths:
#include "..." search starts here:
#include <...> search starts here:
/opt/local/include/gcc6/c++/
/opt/local/include/gcc6/c++//x86_64-apple-darwin13
/opt/local/include/gcc6/c++//backward
/opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include
/opt/local/include
/opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include-fixed
/usr/include
/System/Library/Frameworks
/Library/Frameworks
And then:
$ grep -R '_mm512_' /opt/local/lib/gcc6/ | grep avx512f | head -n 8
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi64 (long long __A, long long __B, long long __C,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi32 (int __A, int __B, int __C, int __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_pd (double __A, double __B, double __C, double __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_ps (float __A, float __B, float __C, float __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi64(e0,e1,e2,e3,e4,e5,e6,e7) \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h: _mm512_set_epi64(e7,e6,e5,e4,e3,e2,e1,e0)
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi32(e0,e1,e2,e3,e4,e5,e6,e7, \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h: _mm512_set_epi32(e15,e14,e13,e12,e11,e10,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0)
...
Upvotes: 0
Views: 4829
Reputation: 4608
_mm512_loadu_epi64 is not available in 32-bit mode. You need to compile for 64-bit mode. In general, AVX512 works best in 64-bit mode.
Upvotes: 0
Reputation: 363922
With no masking, there's no reason for this intrinsic to exist or to ever use it instead of the equivalent _mm512_loadu_si512
. It's just confusing, and could trick human readers into thinking it was a vmovq
zero-extending load of a single epi64
.
Intel's intrinsics finder does specify that it exists, but even current trunk gcc (on Godbolt) doesn't define it.
Almost all AVX512 instructions support merge-masking and zero-masking. Instructions that used to be purely bitwise / whole-register with no meaningful element boundaries now come in 32 and 64-bit element flavours, like vpxord
and vpxorq
. Or vmovdqa32
and vmovdqa64
. But using either version with no masking is still just a normal vector load / store / register-copy, and it's not meaningful to specify anything about element-size for them in the C++ source with intrinsics, only the total vector width.
See also What is the difference between _mm512_load_epi32 and _mm512_load_si512?
SSE* and AVX1/2 options are irrelevent to whether or not GCC headers define this intrinsic in terms of gcc built-ins or not; -mavx512f
already implies all of the Intel SSE/AVX extensions before AVX512.
It is present in clang trunk (but not 7.0 so it was only very recently added).
_mm512_loadu_si512
- supported everywhere, use this_mm512_loadu_epi64
- clang trunk, not gcc._mm512_load_si512
- supported everywhere, use this_mm512_load_epi64
- also supported everywhere, surprisingly._mm512_maskz_loadu_epi64
- supported everywhere, use this for zero-masked loads_mm512_mask_loadu_epi64
- supported everywhere, use this for merge-mask loads.This code compiles on gcc as early as 4.9.0, and mainline (Linux) clang as early as 3.9, both with -march=avx512f
. Or if they support it, -march=skylake-avx512
or -march=knl
. I haven't tested with Apple Clang.
#include <immintrin.h>
__m512i loadu_si512(void *x) { return _mm512_loadu_si512(x); }
__m512i load_epi64(void *x) { return _mm512_load_epi64(x); }
//__m512i loadu_epi64(void *x) { return _mm512_loadu_epi64(x); }
__m512i loadu_maskz(void *x) { return _mm512_maskz_loadu_epi64(0xf0, x); }
__m512i loadu_mask(void *x) { return _mm512_mask_loadu_epi64(_mm512_setzero_si512(), 0xf0, x); }
Godbolt link; you can uncomment the _mm512_loadu_epi64
and flip the compiler to clang trunk to see it work there.
Upvotes: 3