lundi 27 juin 2016

Where is __v2di declared when using -std=c++11 under GCC?

I'm having trouble compiling some code under GCC 4.9 when using -std=c++11. GCC 4.9 is provided under Debian 8.5 (Stable), so its fairly popular.

The relevant code is:

__inline __m128i
clmulepi64_si128 (__m128i a, __m128i b, const int i)
{
    asm ("pclmulqdq %2, %1, %0" : "+x"(a) : "xm"(b), "i"(i));
    return a;
}

Attempting to compile it results in:

In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:43:0,
                 from /usr/include/x86_64-linux-gnu/c++/4.9/bits/opt_random.h:33,
                 from /usr/include/c++/4.9/random:50,
                 from /usr/include/c++/4.9/bits/stl_algo.h:66,
                 from /usr/include/c++/4.9/algorithm:62,
                 ...
error: expected ‘)’ before ‘__builtin_ia32_pclmulqdq128’
 clmulepi64_si128 (__m128i a, __m128i b, const int i)
 ^

It does not make a lot of sense until I go grepping for __builtin_ia32_pclmulqdq128:

$ grep -IR '__builtin_ia32_pclmulqdq128' /usr/lib 2>/dev/null | grep -iv clang
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:  return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:  ((__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)(__m128i)(X),  

It appears GCC performs an intermediate cast to __v2di, but __v2di is missing. Including GCC's <x86intrin.h> super header does not provide it.

I can't find __v2di by grepping through the source files. Its probably there, but I have not been able to locate it. See below for the greps.

Where is __v2di declared or defined when -std=c++11 under GCC?


Here's another twist... It works without -std=..., but it fails with std=c++11:

$ make CXXFLAGS=" -DDEBUG -g3 -O0 -fPIC -march=native" vmac.o
g++ -DDEBUG -g3 -O0 -fPIC -march=native -c vmac.cpp 
$

And:

$ make CXXFLAGS=" -DDEBUG -g3 -O0 -std=c++11 -fPIC -march=native -pipe" vmac.o
g++ -DDEBUG -g3 -O0 -std=c++11 -fPIC -march=native -pipe -c vmac.cpp
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:43:0,
                 from /usr/include/x86_64-linux-gnu/c++/4.9/bits/opt_random.h:33,
                 from /usr/include/c++/4.9/random:50,
                 from /usr/include/c++/4.9/bits/stl_algo.h:66,
                 from /usr/include/c++/4.9/algorithm:62,


$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep 'define'
$

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep 'struct'
$

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep '}'                                                                              
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep '{'
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };

Aucun commentaire:

Enregistrer un commentaire