title: Why is __muldc3 called, when two std::complex are multiplied?
body: <p>I naively assumed, that the complex number multiplication would be inlined by the compiler, for example for this function:</p>
  
  <pre><code>#include &lt;complex&gt;
  
  void mult(std::complex&lt;double&gt; &amp;a, std::complex&lt;double&gt; &amp;b){
      a*=b;
  }
  </code></pre>
  
  <p>However, when complied by gcc (with <code>-O2</code>), the <a href="https://godbolt.org/g/9UbXCy" rel="noreferrer">resulting assembler</a> is surprising (at least for me):</p>
  
  <pre><code>mult(std::complex&lt;double&gt;&amp;, std::complex&lt;double&gt;&amp;):
          pushq   %rbx
          movsd   8(%rdi), %xmm3
          movsd   (%rdi), %xmm2
          movq    %rdi, %rbx
          movsd   8(%rsi), %xmm1
          movsd   (%rsi), %xmm0
          call    __muldc3
          movsd   %xmm0, (%rbx)
          movsd   %xmm1, 8(%rbx)
          popq    %rbx
          ret
  </code></pre>
  
  <p>There is a call to this function <code>__multdc3</code>, which somehow replaced the call to the <code>operator*=</code> (its mangled name would be <code>_ZNSt7complexIdEmLIdEERS0_RKS_IT_E</code> and the complex number would be passed per reference).</p>
  
  <p>However, there seems to be nothing special in the <a href="https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/complex#L295" rel="noreferrer">implementation</a> of the <code>operator*=</code> which would explain the magic:</p>
  
  <pre><code>// 26.2.5/13
    // XXX: This is a grammar school implementation.
    template&lt;typename _Tp&gt;
      template&lt;typename _Up&gt;
      complex&lt;_Tp&gt;&amp;
      complex&lt;_Tp&gt;::operator*=(const complex&lt;_Up&gt;&amp; __z)
      {
        const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
        _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
        _M_real = __r;
        return *this;
  }
  </code></pre>
  
  <p>I must be missing something, thus my question: What is the reason for the resulting assembler?</p>