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?

        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