<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - _mm_movehl_ps pesimised to movaps/shufpd instead of movhlps"
   href="https://llvm.org/bugs/show_bug.cgi?id=26491">26491</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>_mm_movehl_ps pesimised to movaps/shufpd instead of movhlps
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.7
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Keywords</th>
          <td>performance
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>peter@cordes.ca
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>clang sometimes uses a different instruction that the "normal" one for the
intrinsic.  Usually it gets an improvement, but not in this case where it ends
up wasting a movaps and using a bigger instruction.

float hsum_ps(__m128 v) {
    __m128 tmp  = _mm_movehdup_ps(v);     // dest of MOVSHDUP is write-only
    __m128 sums = _mm_add_ps(v, tmp);
    tmp         = _mm_movehl_ps(tmp, sums);
    sums        = _mm_add_ss(sums, tmp);
    return  _mm_cvtss_f32(sums);
}

compiles to: clang 3.7.1 -O3 -march=core2

        movshdup        xmm1, xmm0      # xmm1 = xmm0[1,1,3,3]
        addps   xmm1, xmm0
        movaps  xmm0, xmm1
        shufpd  xmm0, xmm0, 1           # xmm0 = xmm0[1,0]
        addss   xmm0, xmm1
        ret

movhlps is very compact: OF 12 /r,  vs. shufpd being a 5 byte insn.  At least
it doesn't use shufps, which is slow on Core2.  A similar sequence after a loop
produced a movaps/unpckhpd instead of the movhlps.


What I was hoping for (and which gcc produces) is the obvious literal
translation from intrinsics to instructions:

        movshdup xmm1, xmm0
        addps   xmm0, xmm1
        movhlps xmm1, xmm0
        addss   xmm0, xmm1
        ret

I used movshdup first because its destination is write-only.  I can avoid a
movaps without needing the compiler to keep some other variable live so I can
movhlps into it.  (And so I could put it in a function that only takes one
parameter.)  I can't use _mm_undefined_ps() without risk of denormals or NaN
slowdowns.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>