title: Implementing a ticket lock with atomics generates extra mov
body: <p>I wrote a naive implementation of a simple <a href="https://en.wikipedia.org/wiki/Ticket_lock#Implementation_of_Ticket_Lock">ticket lock</a>. The locking part looks like:</p>
  
  <pre><code>struct ticket {
      uint16_t next_ticket;
      uint16_t now_serving;
  };
  
  void lock(ticket* tkt) {
      const uint16_t my_ticket =
          __sync_fetch_and_add(&amp;tkt-&gt;next_ticket, 1); 
      while (tkt-&gt;now_serving != my_ticket) {
          _mm_pause();
          __asm__ __volatile__("":::"memory");
      }   
  }
  </code></pre>
  
  <p>Then I realized that rather than using a gcc intrinsic, I can write this with <code>std::atomic</code>s:</p>
  
  <pre><code>struct atom_ticket {
      std::atomic&lt;uint16_t&gt; next_ticket;
      std::atomic&lt;uint16_t&gt; now_serving;
  };
  
  void lock(atom_ticket* tkt) {
      const uint16_t my_ticket =
          tkt-&gt;next_ticket.fetch_add(1, std::memory_order_relaxed);
      while (tkt-&gt;now_serving.load(std::memory_order_relaxed) != my_ticket) {
          _mm_pause();
      }   
  }
  </code></pre>
  
  <p>These generate <em>almost</em> identical assembly, but the latter generates an additional <code>movzwl</code> instruction. Why is there this extra <code>mov</code>? Is there a better, correct way to write <code>lock()</code>?</p>
  
  <p>Assembly output with <code>-march=native -O3</code>:</p>
  
  <pre><code> 0000000000000000 &lt;lock(ticket*)&gt;:
      0:   b8 01 00 00 00          mov    $0x1,%eax
      5:   66 f0 0f c1 07          lock xadd %ax,(%rdi)
      a:   66 39 47 02             cmp    %ax,0x2(%rdi)
      e:   74 08                   je     18 &lt;lock(ticket*)+0x18&gt;
     10:   f3 90                   pause  
     12:   66 39 47 02             cmp    %ax,0x2(%rdi)
     16:   75 f8                   jne    10 &lt;lock(ticket*)+0x10&gt;
     18:   f3 c3                   repz retq 
     1a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  </code></pre>
  
  <p></p>
  
  <pre><code> 0000000000000020 &lt;lock(atom_ticket*)&gt;:
     20:   ba 01 00 00 00          mov    $0x1,%edx
     25:   66 f0 0f c1 17          lock xadd %dx,(%rdi)
     2a:   48 83 c7 02             add    $0x2,%rdi
     2e:   eb 02                   jmp    32 &lt;lock(atom_ticket*)+0x12&gt;
     30:   f3 90                   pause  
  =&gt; 32:   0f b7 07                movzwl (%rdi),%eax &lt;== ???
     35:   66 39 c2                cmp    %ax,%dx
     38:   75 f6                   jne    30 &lt;lock(atom_ticket*)+0x10&gt;
     3a:   f3 c3                   repz retq 
  </code></pre>
  
  <p>Why not just <code>cmp (%rdi),%dx</code> directly?</p>