On Sun, Jan 20, 2019 at 11:40 AM Alexander Monakov <amona...@ispras.ru> wrote: > > Hi, > > PR 88698 ("Relax generic vector conversions") is asking to be more permissive > about type compatibility for generic vector types. While I don't think that's > a good idea per se, from a "compiler user" point of view I also see how > writing > code for SSE/AVX using both generic vectors and x86 intrinsics is inconvenient > because all intrinsics use the same type such as __m128i, regardless of > whether > they operate on 8/16/32/64-bit signed/unsigned lanes. > > My solution to that is to introduce a union type that holds both the type > accepted by intrinsics and generic vector types used by my code. It also has > an interesting effect that each statement spells out the lane type. > > Is it appropriate to showcase this approach in our documentation, as done in > this patch? What to do with the PR, should I leave it open?
I think it's appropriate to have this kind of hints in the documentation. I'm not sure whether it's permitted to use this in C++ or not (and whether the C usage is now officially sanctioned other than via a non-normative footnote) - but at least GCC will guarantee that it works. Might be interesting to show how to do argument marshalling with the same union. Richard. > PR c/88698 > * doc/extend.texi (Vector Extensions): Add an example of using vector > types together with x86 intrinsics. > > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -10632,6 +10632,40 @@ v4si g = __builtin_convertvector (f, v4si); /* g is > @{1,-2,3,7@} */ > v4si h = __builtin_convertvector (c, v4si); /* h is @{1,5,0,10@} */ > @end smallexample > > +@cindex vector types, using with x86 intrinsics > +Sometimes it is desirable to write code using a mix of generic vector > +operations (for clarity) and machine-specific vector intrinsics (to > +access vector instructions that are not exposed via generic built-ins). > +On x86, intrinsic functions for integer vectors typically use the same > +vector type @code{__m128i} irrespective of how they interpret the vector, > +making it necessary to cast their arguments and return values from/to > +other vector types. In C, you can make use of a @code{union} type: > +@c In C++ such type punning via a union is not allowed by the language > +@smallexample > +#include <immintrin.h> > + > +typedef unsigned char u8x16 __attribute__ ((vector_size (16))); > +typedef unsigned int u32x4 __attribute__ ((vector_size (16))); > + > +typedef union @{ > + u8x16 u8; > + u32x4 u32; > + __m128i mm; > +@} v128; > +@end smallexample > + > +@noindent > +for variables that can be used with both built-in operations and x86 > +intrinsics: > + > +@smallexample > +v128 x, y = @{ 0 @}; > +memcpy (&x, ptr, sizeof x); > +y.u8 += 0x80; > +x.mm = _mm_adds_epu8 (x.mm, y.mm); > +x.u32 &= 0xffffff; > +@end smallexample > + > @node Offsetof > @section Support for @code{offsetof} > @findex __builtin_offsetof