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

Reply via email to