title: Strange uses of movzx by Clang and GCC
body: <p>I know that <code>movzx</code> can be used for dependency breaking, but I stumbled on some <code>movzx</code> uses by both Clang and GCC that I really can't see what good they are for. Here's a simple example I tried on Godbolt compiler explorer:</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdint.h&gt;
  
  int add2bytes(uint8_t* a, uint8_t* b) {
      return uint8_t(*a + *b);
  }
  </code></pre>
  <p>with GCC 12 <code>-O3</code>:</p>
  <pre class="lang-text prettyprint-override"><code>add2bytes(unsigned char*, unsigned char*):
          movzx   eax, BYTE PTR [rsi]
          add     al, BYTE PTR [rdi]
          movzx   eax, al
          ret
  </code></pre>
  <p>If I understand correctly, the first <code>movzx</code> here breaks dependency on previous <code>eax</code> value, but what is the second <code>movzx</code> doing? I don't think there's any dependency it can break, and it shouldn't affect the result either.</p>
  <p>with clang 14 <code>-O3</code>, it's even more weird:</p>
  <pre class="lang-text prettyprint-override"><code>add2bytes(unsigned char*, unsigned char*):                       # @add2bytes(unsigned char*, unsigned char*)
          mov     al, byte ptr [rsi]
          add     al, byte ptr [rdi]
          movzx   eax, al
          ret
  </code></pre>
  <p>It uses <code>mov</code> where <code>movzx</code> seems more reasonable, and then zero extends <code>al</code> to <code>eax</code>, but wouldn't it be much better to do <code>movzx</code> at the start?</p>
  <p>I have 2 more examples here: <a href="https://godbolt.org/z/z45xr4hq1" rel="noreferrer">https://godbolt.org/z/z45xr4hq1</a>
  GCC generates both sensible and strange <code>movzx</code>, and Clang's use of <code>mov r8 m</code> and <code>movzx</code> just makes no sense to me. I also tried adding <code>-march=skylake</code> to make sure this isn't a feature for really old architectures, but the generated assembly looks more or less the same.</p>
  <p>The closest post I have found is <a href="https://stackoverflow.com/a/64915219/14730360">https://stackoverflow.com/a/64915219/14730360</a> where they showed similar <code>movzx</code> uses that seem useless and/or out of place.</p>
  <p>Do the compilers really use <code>movzx</code> poorly here, or am I missing something?</p>
  <p>Edit: I have opened bug reports for Clang and GCC:</p>
  <p><a href="https://github.com/llvm/llvm-project/issues/56498" rel="noreferrer">https://github.com/llvm/llvm-project/issues/56498</a></p>
  <p><a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106277" rel="noreferrer">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106277</a></p>
  <p>Temporary workarounds using inline assembly:
  <a href="https://godbolt.org/z/7qob8G3j7" rel="noreferrer">https://godbolt.org/z/7qob8G3j7</a></p>
  <pre><code>#define addb(a, b) asm (\
      &quot;addb %1, %b0&quot;\
      : &quot;+r&quot;(a) : &quot;mi&quot;(b))
  
  int add2bytes(uint8_t* a, uint8_t* b) {
      int ret = *a;
      addb(ret, *b);
      return ret;
  }
  </code></pre>
  <p>Now Clang -O3 produces:</p>
  <pre><code>add2bytes(unsigned char*, unsigned char*):                       # @add2bytes(unsigned char*, unsigned char*)
          movzx   eax, byte ptr [rdi]
          add     al, byte ptr [rsi]
          ret
  </code></pre>