Language: C++

// g++ -o D2 D2.cpp -std=c++11 -O2 -mavx2 でコンパイルする

#include <x86intrin.h>
#include <bits/stdc++.h>
using namespace std;
 
using tpl = tuple<char, int>;
typedef pair<int,int> pii;
typedef long long ll;

void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}

#define ALIGNED(n) __attribute((aligned(n)))


int N;
ALIGNED(32) int A[1000100];
ALIGNED(32) int B[1000100];

int calc(int *A, int *B, int N){
    __m256i d = {0};
    for(int i = 0; i < N / 8; i++){
        //:TODO  左シフトと右シフトがレーン境界を超えず、↓のロジックだとうまくいかない
        // なんとかしたい
        __m256i a1 = _mm256_load_si256(reinterpret_cast<__m256i*>(&A[i*8]));
        __m256i a2 = _mm256_or_si256(_mm256_srli_si256(a1, 4),  _mm256_slli_si256(a1, 28));
        __m256i a3 = _mm256_or_si256(_mm256_srli_si256(a1, 8),  _mm256_slli_si256(a1, 24));
        __m256i a4 = _mm256_or_si256(_mm256_srli_si256(a1, 12), _mm256_slli_si256(a1, 20));
        __m256i a5 = _mm256_or_si256(_mm256_srli_si256(a1, 16), _mm256_slli_si256(a1, 16));
        __m256i a6 = _mm256_or_si256(_mm256_srli_si256(a1, 20), _mm256_slli_si256(a1, 12));
        __m256i a7 = _mm256_or_si256(_mm256_srli_si256(a1, 24), _mm256_slli_si256(a1, 8));
        __m256i a8 = _mm256_or_si256(_mm256_srli_si256(a1, 28), _mm256_slli_si256(a1, 4));

        __m256i *p = reinterpret_cast<__m256i*>(B);

        for(int j = 0; j < N / 8; j++){
            __m256i b = _mm256_load_si256(p + j);
            __m256i c;

            c = _mm256_add_epi32(a1, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a2, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a3, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a4, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a5, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a6, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a7, b);
            d = _mm256_xor_si256(c, d);

            c = _mm256_add_epi32(a8, b);
            d = _mm256_xor_si256(c, d);
        }
    }

    ALIGNED(32) int C[8];
    _mm256_store_si256(reinterpret_cast<__m256i*>(C), d);

    int res = 0;
    for(int i = 0; i < 8; i++){
        res ^= C[i];
    }

    // 端数の計算
    for(int i = N / 8 * 8; i < N; i++){
        for(int j = 0; j < N; j++){
            res ^= (A[j] + B[i]);
        }
    }

    for(int i = N / 8 * 8; i < N; i++){
        for(int j = 0; j < N / 8 * 8; j++){
            res ^= (B[j] + A[i]);
        }
    }
    

    return res;
 }


void simple(){
    int ans = 0;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            ans ^= A[i] + B[j];
        }
    }
    cout << ans << endl;
}

void simd(){
    cout << calc(A, B, N) << endl;
}


int main(){

    fastStream();

    cin >> N;
    for(int i = 0; i < N; i++) cin >> A[i];
    for(int i = 0; i < N; i++) cin >> B[i];

    //simple();
    simd();

    return 0;
}


Compiler output:
a.cc: In function 'int calc(int*, int*, int)':
a.cc:25:75: warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
   25 |         __m256i a1 = _mm256_load_si256(reinterpret_cast<__m256i*>(&A[i*8]));
      |                                                                           ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/14/include/immintrin.h:53,
                 from /usr/lib/gcc/x86_64-linux-gnu/14/include/x86intrin.h:32,
                 from a.cc:3:
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:32:37: note: called from here
   32 |         __m256i a8 = _mm256_or_si256(_mm256_srli_si256(a1, 28), _mm256_slli_si256(a1, 4));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:31:37: note: called from here
   31 |         __m256i a7 = _mm256_or_si256(_mm256_srli_si256(a1, 24), _mm256_slli_si256(a1, 8));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:30:37: note: called from here
   30 |         __m256i a6 = _mm256_or_si256(_mm256_srli_si256(a1, 20), _mm256_slli_si256(a1, 12));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:29:37: note: called from here
   29 |         __m256i a5 = _mm256_or_si256(_mm256_srli_si256(a1, 16), _mm256_slli_si256(a1, 16));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:28:37: note: called from here
   28 |         __m256i a4 = _mm256_or_si256(_mm256_srli_si256(a1, 12), _mm256_slli_si256(a1, 20));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:27:37: note: called from here
   27 |         __m256i a3 = _mm256_or_si256(_mm256_srli_si256(a1, 8),  _mm256_slli_si256(a1, 24));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:574:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_or_si256(__m256i, __m256i)': target specific option mismatch
  574 | _mm256_or_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~
a.cc:26:37: note: called from here
   26 |         __m256i a2 = _mm256_or_si256(_mm256_srli_si256(a1, 4),  _mm256_slli_si256(a1, 28));
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/14/include/immintrin.h:43:
/usr/lib/gcc/x86_64-linux-gnu/14/include/avxintrin.h:915:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_load_si256(const __m256i*)': target specific option mismatch
  915 | _mm256_load_si256 (__m256i const *__P)
      | ^~~~~~~~~~~~~~~~~
a.cc:25:39: note: called from here
   25 |         __m256i a1 = _mm256_load_si256(reinterpret_cast<__m256i*>(&A[i*8]));
      |                      ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:62:33: note: called from here
   62 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:61:33: note: called from here
   61 |             c = _mm256_add_epi32(a8, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:59:33: note: called from here
   59 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:58:33: note: called from here
   58 |             c = _mm256_add_epi32(a7, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:56:33: note: called from here
   56 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:55:33: note: called from here
   55 |             c = _mm256_add_epi32(a6, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:53:33: note: called from here
   53 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:52:33: note: called from here
   52 |             c = _mm256_add_epi32(a5, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:50:33: note: called from here
   50 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:49:33: note: called from here
   49 |             c = _mm256_add_epi32(a4, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:47:33: note: called from here
   47 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:46:33: note: called from here
   46 |             c = _mm256_add_epi32(a3, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific option mismatch
  913 | _mm256_xor_si256 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:44:33: note: called from here
   44 |             d = _mm256_xor_si256(c, d);
      |                 ~~~~~~~~~~~~~~~~^~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:119:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_add_epi32(__m256i, __m256i)': target specific option mismatch
  119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
      | ^~~~~~~~~~~~~~~~
a.cc:43:33: note: called from here
   43 |             c = _mm256_add_epi32(a2, b);
      |                 ~~~~~~~~~~~~~~~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/14/include/avx2intrin.h:913:1: error: inlining failed in call to 'always_inline' '__m256i _mm256_xor_si256(__m256i, __m256i)': target specific opt