AVX - cast from YMM to XMM without overhead?

Marc Glisse marc.glisse@inria.fr
Sat Jun 23 17:54:00 GMT 2012


On Sat, 23 Jun 2012, Dag Lem wrote:

> Using gcc 4.7.0, I am trying to use vector extensions and AVX builtins
> to sum 8 complex numbers, where the real and imaginary parts are
> stored in separate YMM registers, and store the result in m64. In
> other words, I'd like to achieve the following:
>
>  v2sf* z = ...;
>  v8sf re = ...;
>  v8sf im = ...;
>  *z  = { sum(re[0..7]), sum(im[0..7]) };
>
> My first attempt at this was:
>
>  v8sf a = __builtin_ia32_haddps256(re, im);         // iirr iirr
>  v4sf b = __builtin_ia32_vextractf128_ps256(a, 1);
>  v4sf c = (v4sf)a + b;                              //      iirr
>  v4sf d = __builtin_ia32_haddps(c, c);              //      irir
>  *z = (v2sf)d;                                      //        ir
>
> However, gcc does not seem to allow casting between vectors of
> different lengths (why?!).

Ugly.

> Hence, my second attempt is as follows:
>
>  v8sf a = __builtin_ia32_haddps256(re, im);         // iirr iirr
>  v4sf b = __builtin_ia32_vextractf128_ps256(a, 1);
>  v4sf c = *((v4sf*)&a) + b;                         //      iirr
>  v4sf d = __builtin_ia32_haddps(c, c);              //      irir
>  __builtin_ia32_storelps(z, d);                     //        ir
>
> The problem with this is that in the calculation of "c = a + b", gcc
> generates an intermediate instruction (vmovdqa) to store the contents
> of the YMM register holding "a" to memory, instead of directly
> accessing the low 128 bits via the corresponding XMM register.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53101

> I have also looked into using inline assembly to avoid the overhead,
> however as far as I can tell it is not possible to use YMM registers
> as parameters.

Yes it is, you may want to re-read the doc remembering that the YMM 
registers are the XMM registers (you just use them more fully).

> Is there any way to cast from a YMM to an XMM register without
> incurring any performance penalty?

ISTR that _mm256_extractf128_ps(*,0) is properly optimized to nothing when 
possible (I may misremember).

-- 
Marc Glisse



More information about the Gcc-help mailing list