title: Does RSQRTSS break the dependency on the destination register?
body: <p>Using <a href="https://uica.uops.info/" rel="nofollow noreferrer">uiCA</a> I produced a trace table for the following code.</p>
  <pre><code>cvtsi2ss xmm0, eax
  addss xmm0, xmm0
  </code></pre>
  <p><a href="https://uica.uops.info/tmp/780bce9e56ee4a718d5369deb1326215_trace.html" rel="nofollow noreferrer">https://uica.uops.info/tmp/780bce9e56ee4a718d5369deb1326215_trace.html</a></p>
  <p>You can see that each <code>cvtsi2ss</code> has to wait for the previous iteration to finish because it depends on some bits (<code>32:127</code>) of <code>xmm0</code>.</p>
  <p>However, changing <code>cvtsi2ss</code> to <code>rsqrtss</code> makes a big difference.</p>
  <pre><code>rsqrtss xmm0, xmm1
  addss xmm0, xmm0
  </code></pre>
  <p><a href="https://uica.uops.info/tmp/8897a7d45c8348e68279aea4d0b18e15_trace.html" rel="nofollow noreferrer">https://uica.uops.info/tmp/8897a7d45c8348e68279aea4d0b18e15_trace.html</a></p>
  <p>Each <code>rsqrtss</code> executes in parallel with the previous iteration. I don't understand because <code>rsqrtss</code> produces an output with bits <code>32:127</code> unchanged, just like <code>cvtsi2ss</code>, so I think it should wait for any operation on the output register to finish, just like <code>cvtsi2ss</code> did.</p>
  <hr />
  <p>After reading the answer, I ran a simple test, and it seems sure that uiCA has a bug.</p>
  <p><a href="https://www.intel.com/content/www/us/en/developer/articles/tool/architecture-code-analyzer.html" rel="nofollow noreferrer">IACA</a> also fails to catch the output dependency.</p>
  <p>Please correct me if the test code is wrong.</p>
  <pre><code>__asm__ (
      R&quot;(.section .text
      .balign 16
  noXor:
      mov eax, 0x3f800000
      movd xmm1, eax
      rdtscp
      shl rdx, 32
      or rax, rdx
      mov rdi, rax
      mov ecx, 1 &lt;&lt; 30
      jmp noXor_loop
      .balign 16
  noXor_loop:
      rsqrtss xmm0, xmm1
      addss xmm0, xmm0
      dec ecx
      jnz noXor_loop
      rdtscp
      shl rdx, 32
      or rax, rdx
      sub rax, rdi
      ret
      .balign 16
  yesXor:
      mov eax, 0x3f800000
      movd xmm1, eax
      rdtscp
      shl rdx, 32
      or rax, rdx
      mov rdi, rax
      mov ecx, 1 &lt;&lt; 30
      jmp yesXor_loop
      .balign 16
  yesXor_loop:
      xorps xmm0, xmm0
      rsqrtss xmm0, xmm1
      addss xmm0, xmm0
      dec ecx
      jnz yesXor_loop
      rdtscp
      shl rdx, 32
      or rax, rdx
      sub rax, rdi
      ret)&quot;
  );
  
  unsigned long long noXor(void);
  unsigned long long yesXor(void);
  
  #include &lt;stdio.h&gt;
  
  int main() {
      for (int i = 0; i &lt; 4; ++i) {
          printf(&quot;noXor: %llu yesXor: %llu\n&quot;, noXor(), yesXor());
      }
      return 0;
  }
  </code></pre>
  <pre><code>noXor: 4978836501 yesXor: 696810039
  noXor: 4971780086 yesXor: 690780109
  noXor: 4977293771 yesXor: 687404710
  noXor: 5499602729 yesXor: 687954399
  </code></pre>