Why is this piece of code creating radically different assembly code in C and C ++?

struct v { int val[16]; }; struct v test(struct va, struct vb) { struct v res; for (int i = 0; i < 16; i++) res.val[i] = a.val[i] + b.val[i]; return res; } 

Compiling as C ++, GCC 7.2 emits:

  push r10 vmovdqu32 zmm0, ZMMWORD PTR [rsp+16] mov rax, rdi vpaddd zmm0, zmm0, ZMMWORD PTR [rsp+80] lea r10, [rsp+16] vmovdqu32 ZMMWORD PTR [rdi], zmm0 pop r10 

Compilation as C:

  lea r10, [rsp+8] and rsp, -64 mov rax, rdi push QWORD PTR [r10-8] push rbp mov rbp, rsp push r10 vmovdqu32 zmm0, ZMMWORD PTR [r10] vpaddd zmm0, zmm0, ZMMWORD PTR [r10+64] vmovdqa64 ZMMWORD PTR [rbp-112], zmm0 vmovdqa64 xmm0, XMMWORD PTR [rbp-112] vmovups XMMWORD PTR [rdi], xmm0 vmovdqa64 xmm0, XMMWORD PTR [rbp-96] vmovups XMMWORD PTR [rdi+16], xmm0 vmovdqa64 xmm0, XMMWORD PTR [rbp-80] vmovups XMMWORD PTR [rdi+32], xmm0 vmovdqa64 xmm0, XMMWORD PTR [rbp-64] vmovups XMMWORD PTR [rdi+48], xmm0 pop r10 pop rbp lea rsp, [r10-8] 

Compiled as C versus C ++ in the Godbolt compiler explorer:

clang x86 asm: https://godbolt.org/g/FfrKTf
gcc x86 asm: https://godbolt.org/g/SZQqqt

The same code fragment produces significantly different code for C and C ++ in both gcc and clang:

  • The auto-vectorization cycle is different: gcc using unequal loads / storages, but g ++ using a scalar to the alignment border, with -march=sandybridge or something narrower than AVX2.

    This does not apply to x86: the same thing happens with automatic vectorization for the AArch64 SIM card.

  • Version C actually stores the results in a local res on the stack, and then uses copies of SIMD copies from there to the return value pointer (sometimes with a different vector width for the copy than for a loop that just saved data).

    With auto-vectorization ( -fno-tree-vectorize ) -fno-tree-vectorize gcc still uses the SIMD load / store to copy the results.

Does anyone know why this is so?

Is there any alignment guarantee that is in the C ++ standard but not in the C standard? Is this an ABI problem? Or is this some weird compilation option in the compiler explorer?

+5
source share

Source: https://habr.com/ru/post/1275410/


All Articles