title: Atomic operations and code generation for gcc
body: <p>I am curring looking at some assembly generated for atomic operations by gcc. I tried the following short sequence:</p>
  
  <pre><code>int x1;
  int x2;
  
  int foo;
  
  void test()
  {
    __atomic_store_n( &amp;x1, 1, __ATOMIC_SEQ_CST );
    if( __atomic_load_n( &amp;x2  ,__ATOMIC_SEQ_CST ))
      return;
  
    foo = 4;
  }
  </code></pre>
  
  <p>Looking at Herb Sutter's atomic weapons talk on code generation, he mentions that the X86 manual mandates to use <code>xchg</code> for atomic stores and a simple <code>mov</code> for atomic reads. So I was expecting something along the lines of:</p>
  
  <pre><code>test():
  .LFB0:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      movl    $1, %eax
      xchg    %eax, x1(%rip)
      movl    x2(%rip), %eax
      testl   %eax, %eax
      setne   %al
      testb   %al, %al
      je      .L2
      jmp     .L1
  .L2:
      movl    $4, foo(%rip)
  .L1:
      popq    %rbp
      .cfi_def_cfa 7, 8
      ret
      .cfi_endproc
  </code></pre>
  
  <p>Where the memory fence is implicit because of the locked <code>xchg</code> instruction.</p>
  
  <p>However if I compile this using <code>gcc -march=core2 -S test.cc</code> I get the following:</p>
  
  <pre><code>test():
  .LFB0:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      movl    $1, %eax
      movl    %eax, x1(%rip)
      mfence
      movl    x2(%rip), %eax
      testl   %eax, %eax
      setne   %al
      testb   %al, %al
      je      .L2
      jmp     .L1
  .L2:
      movl    $4, foo(%rip)
  .L1:
      popq    %rbp
      .cfi_def_cfa 7, 8
      ret
      .cfi_endproc
  </code></pre>
  
  <p>So instead of using a <code>xchg</code> operation gcc here uses a <code>mov + mfence</code> combination. What is the reason here for this code generation, which differs from the one mandated by the x86 architecture according to Herb Sutter?</p>