@@ -30,20 +30,22 @@ void complexMultiply (const float* __restrict a, const float* __restrict b, floa
3030
3131#if YUP_USE_AVX_INTRINSICS && YUP_USE_FMA_INTRINSICS
3232 constexpr int simdWidth = 4 ;
33+ const __m256 signs = _mm256_set_ps (1 .0f , -1 .0f , 1 .0f , -1 .0f , 1 .0f , -1 .0f , 1 .0f , -1 .0f );
34+
3335 for (; i <= complexPairs - simdWidth; i += simdWidth)
3436 {
3537 const int idx = i * 2 ;
3638
37- __m256 av = _mm256_loadu_ps (a + idx);
38- __m256 bv = _mm256_loadu_ps (b + idx);
39-
40- const __m256 aShuffled = _mm256_permute_ps (av, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
41- const __m256 bShuffled = _mm256_permute_ps (bv, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
39+ const __m256 av = _mm256_loadu_ps (a + idx);
40+ const __m256 bv = _mm256_loadu_ps (b + idx);
4241
43- __m256 realPart = _mm256_fmsub_ps (av, bv, _mm256_mul_ps (aShuffled, bShuffled));
44- __m256 imagPart = _mm256_fmadd_ps (av, bShuffled, _mm256_mul_ps (aShuffled, bv));
42+ const __m256 aReal = _mm256_permute_ps (av, _MM_SHUFFLE (2 , 2 , 0 , 0 ));
43+ const __m256 aImag = _mm256_permute_ps (av, _MM_SHUFFLE (3 , 3 , 1 , 1 ));
44+ const __m256 bSwapped = _mm256_permute_ps (bv, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
45+ const __m256 realProducts = _mm256_mul_ps (aReal, bv);
46+ const __m256 imagProducts = _mm256_mul_ps (aImag, bSwapped);
4547
46- __m256 interleaved = _mm256_blend_ps (realPart, imagPart, 0b10101010 );
48+ __m256 interleaved = _mm256_fmadd_ps (imagProducts, signs, realProducts );
4749
4850 if (accumulate)
4951 interleaved = _mm256_add_ps (_mm256_loadu_ps (y + idx), interleaved);
@@ -53,20 +55,22 @@ void complexMultiply (const float* __restrict a, const float* __restrict b, floa
5355
5456#elif YUP_USE_SSE_INTRINSICS
5557 constexpr int simdWidth = 2 ;
58+ const __m128 signs = _mm_set_ps (1 .0f , -1 .0f , 1 .0f , -1 .0f );
59+
5660 for (; i <= complexPairs - simdWidth; i += simdWidth)
5761 {
5862 const int idx = i * 2 ;
5963
60- __m128 av = _mm_loadu_ps (a + idx);
61- __m128 bv = _mm_loadu_ps (b + idx);
62-
63- const __m128 aShuffled = _mm_shuffle_ps (av, av, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
64- const __m128 bShuffled = _mm_shuffle_ps (bv, bv, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
64+ const __m128 av = _mm_loadu_ps (a + idx);
65+ const __m128 bv = _mm_loadu_ps (b + idx);
6566
66- __m128 realPart = _mm_sub_ps (_mm_mul_ps (av, bv), _mm_mul_ps (aShuffled, bShuffled));
67- __m128 imagPart = _mm_add_ps (_mm_mul_ps (av, bShuffled), _mm_mul_ps (aShuffled, bv));
67+ const __m128 aReal = _mm_shuffle_ps (av, av, _MM_SHUFFLE (2 , 2 , 0 , 0 ));
68+ const __m128 aImag = _mm_shuffle_ps (av, av, _MM_SHUFFLE (3 , 3 , 1 , 1 ));
69+ const __m128 bSwapped = _mm_shuffle_ps (bv, bv, _MM_SHUFFLE (2 , 3 , 0 , 1 ));
70+ const __m128 realProducts = _mm_mul_ps (aReal, bv);
71+ const __m128 imagProducts = _mm_mul_ps (aImag, bSwapped);
6872
69- __m128 interleaved = _mm_unpacklo_ps (realPart, imagPart );
73+ __m128 interleaved = _mm_add_ps (realProducts, _mm_mul_ps (imagProducts, signs) );
7074
7175 if (accumulate)
7276 interleaved = _mm_add_ps (_mm_loadu_ps (y + idx), interleaved);
0 commit comments