O código a seguir produz um assembly que executa condicionalmente o SIMD no GCC 12.3 quando compilado com -O3
. Para completar, o código sempre executa SIMD no GCC 13.2 e nunca executa SIMD no clang 17.0.1.
#include <array>
__attribute__((noinline)) void fn(std::array<int, 4>& lhs, const std::array<int, 4>& rhs)
{
for (std::size_t idx = 0; idx != 4; ++idx) {
lhs[idx] = lhs[idx] + rhs[idx];
}
}
Aqui está o link em godbolt.
Aqui está a montagem real do GCC 12.3 (com -O3):
fn(std::array<int, 4ul>&, std::array<int, 4ul> const&):
lea rdx, [rsi+4]
mov rax, rdi
sub rax, rdx
cmp rax, 8
jbe .L2
movdqu xmm0, XMMWORD PTR [rsi]
movdqu xmm1, XMMWORD PTR [rdi]
paddd xmm0, xmm1
movups XMMWORD PTR [rdi], xmm0
ret
.L2:
mov eax, DWORD PTR [rsi]
add DWORD PTR [rdi], eax
mov eax, DWORD PTR [rsi+4]
add DWORD PTR [rdi+4], eax
mov eax, DWORD PTR [rsi+8]
add DWORD PTR [rdi+8], eax
mov eax, DWORD PTR [rsi+12]
add DWORD PTR [rdi+12], eax
ret
Estou muito interessado em saber a) o propósito das primeiras 5 instruções de montagem eb) se há algo que possa ser feito para fazer com que o GCC 12.3 emita o código do GCC 13.2 (idealmente, sem escrever manualmente o SSE).