<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - x86-64: std::atomic<T> is not atomic for a 16 byte object with -mno-cx16"
   href="https://bugs.llvm.org/show_bug.cgi?id=34498">34498</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>x86-64: std::atomic<T> is not atomic for a 16 byte object with -mno-cx16
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>peter@cordes.ca
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>struct A{
    int a;
    int b;
    double c;
};

#include <atomic>
std::atomic<A> shared_struct;

void update_shared2(A tmp) {
    shared_struct.store(tmp, std::memory_order_relaxed);
    // shared_struct = tmp;  // same buggy asm with libc++
}

Godbolt compiler explorer: <a href="https://godbolt.org/g/drmtAe">https://godbolt.org/g/drmtAe</a>

clang 6.0.0 (trunk 312520) -std=c++11 -stdlib=libc++ -Wall -Wextra -O3
-march=skylake -mno-cx16

update_shared2(A):                   # @update_shared2(A)
        mov     qword ptr [rip + shared_struct], rdi
        vmovsd  qword ptr [rip + shared_struct+8], xmm0
        ret

Two separate stores are obviously not atomic!!
This might actually be a libc++ bug. The asm output is different with
-stdlib=libstdc++:

        sub     rsp, 24
        mov     qword ptr [rsp + 8], rdi
        vmovsd  qword ptr [rsp + 16], xmm0
        lea     rdx, [rsp + 8]
        mov     edi, 16
        mov     esi, shared_struct
        xor     ecx, ecx
        call    __atomic_store
        add     rsp, 24
        ret
        mov     rdi, rax
        call    __clang_call_terminate




-----

correct clang4.0 output with libc++ (same options)

update_shared2(A):                   # @update_shared2(A)
        push    rax
        mov     rax, rdi
        vmovq   rdx, xmm0
        mov     edi, shared_struct
        mov     rsi, rax
        call    __sync_lock_test_and_set_16
        pop     rax
        ret</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>