<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 --- - Incorrect use of phsubw"
   href="https://llvm.org/bugs/show_bug.cgi?id=31714">31714</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Incorrect use of phsubw
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

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

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

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

        <tr>
          <th>Component</th>
          <td>Backend: X86
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>andrew.b.adams@gmail.com
          </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>The following .ll defines two functions. The first computes the absolute
difference between adjacent elements in a vector (a > b ? a - b : b - a). The
second just computes the difference (a - b):

define <8 x i16> @horizontal_abs_diff(<16 x i16> * %src) {
  %v1 = load <16 x i16>, <16 x i16>* %src
  %evens = shufflevector <16 x i16> %v1, <16 x i16> undef, <8 x i32> <i32 0,
i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
  %odds = shufflevector <16 x i16> %v1, <16 x i16> undef, <8 x i32> <i32 1, i32
3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
  %d1 = sub <8 x i16> %evens, %odds
  %d2 = sub <8 x i16> %odds, %evens
  %cmp = icmp ugt <8 x i16> %evens, %odds
  %res = select <8 x i1> %cmp, <8 x i16> %d1, <8 x i16> %d2
  ret <8 x i16> %res
}

define <8 x i16> @horizontal_diff(<16 x i16> * %src) {
  %v1 = load <16 x i16>, <16 x i16>* %src
  %evens = shufflevector <16 x i16> %v1, <16 x i16> undef, <8 x i32> <i32 0,
i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
  %odds = shufflevector <16 x i16> %v1, <16 x i16> undef, <8 x i32> <i32 1, i32
3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
  %d1 = sub <8 x i16> %evens, %odds
  ret <8 x i16> %d1
}

When compiled for an architecture with phsubw, both produce the same assembly:

$ llc repro.ll -mcpu=core2 -filetype=asm -o -

        .text
        .def     horizontal_abs_diff;
        .scl    2;
        .type   32;
        .endef
        .globl  horizontal_abs_diff
        .p2align        4, 0x90
horizontal_abs_diff:                    # @horizontal_abs_diff
# BB#0:
        movdqa  (%rcx), %xmm0
        phsubw  16(%rcx), %xmm0
        retq

        .def     horizontal_diff;
        .scl    2;
        .type   32;
        .endef
        .globl  horizontal_diff
        .p2align        4, 0x90
horizontal_diff:                        # @horizontal_diff
# BB#0:
        movdqa  (%rcx), %xmm0
        phsubw  16(%rcx), %xmm0
        retq

That code just computes the horizontal difference in both cases, and so the
outputs are incorrect for the absolute difference case. Compiling without
phsubw available produces meaningfully two different functions, and the outputs
are correct:

$ ../llvm/trunk/build/bin/llc repro.ll -mcpu=native -mattr=-ssse3 -filetype=asm
-o -
        .text
        .def     horizontal_abs_diff;
        .scl    2;
        .type   32;
        .endef
        .section        .rdata,"dr"
        .p2align        4
.LCPI0_0:
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .short  32768                   # 0x8000
        .text
        .globl  horizontal_abs_diff
        .p2align        4, 0x90
horizontal_abs_diff:                    # @horizontal_abs_diff
# BB#0:
        movdqa  (%rcx), %xmm1
        movdqa  16(%rcx), %xmm2
        pshuflw $232, %xmm2, %xmm0      # xmm0 = xmm2[0,2,2,3,4,5,6,7]
        pshufhw $232, %xmm0, %xmm0      # xmm0 = xmm0[0,1,2,3,4,6,6,7]
        pshufd  $232, %xmm0, %xmm3      # xmm3 = xmm0[0,2,2,3]
        pshuflw $232, %xmm1, %xmm0      # xmm0 = xmm1[0,2,2,3,4,5,6,7]
        pshufhw $232, %xmm0, %xmm0      # xmm0 = xmm0[0,1,2,3,4,6,6,7]
        pshufd  $232, %xmm0, %xmm0      # xmm0 = xmm0[0,2,2,3]
        punpcklqdq      %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0]
        pshuflw $231, %xmm2, %xmm2      # xmm2 = xmm2[3,1,2,3,4,5,6,7]
        pshufhw $231, %xmm2, %xmm2      # xmm2 = xmm2[0,1,2,3,7,5,6,7]
        pshufd  $232, %xmm2, %xmm2      # xmm2 = xmm2[0,2,2,3]
        pshuflw $177, %xmm2, %xmm2      # xmm2 = xmm2[1,0,3,2,4,5,6,7]
        pshuflw $231, %xmm1, %xmm1      # xmm1 = xmm1[3,1,2,3,4,5,6,7]
        pshufhw $231, %xmm1, %xmm1      # xmm1 = xmm1[0,1,2,3,7,5,6,7]
        pshufd  $232, %xmm1, %xmm1      # xmm1 = xmm1[0,2,2,3]
        pshuflw $177, %xmm1, %xmm1      # xmm1 = xmm1[1,0,3,2,4,5,6,7]
        punpcklqdq      %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0]
        movdqa  %xmm0, %xmm2
        psubw   %xmm1, %xmm2
        movdqa  %xmm1, %xmm3
        psubw   %xmm0, %xmm3
        movdqa  .LCPI0_0(%rip), %xmm4   # xmm4 =
[32768,32768,32768,32768,32768,32768,32768,32768]
        pxor    %xmm4, %xmm0
        pxor    %xmm4, %xmm1
        pcmpgtw %xmm1, %xmm0
        pand    %xmm0, %xmm2
        pandn   %xmm3, %xmm0
        por     %xmm2, %xmm0
        retq

        .def     horizontal_diff;
        .scl    2;
        .type   32;
        .endef
        .globl  horizontal_diff
        .p2align        4, 0x90
horizontal_diff:                        # @horizontal_diff
# BB#0:
        movdqa  (%rcx), %xmm1
        movdqa  16(%rcx), %xmm2
        pshuflw $232, %xmm2, %xmm0      # xmm0 = xmm2[0,2,2,3,4,5,6,7]
        pshufhw $232, %xmm0, %xmm0      # xmm0 = xmm0[0,1,2,3,4,6,6,7]
        pshufd  $232, %xmm0, %xmm3      # xmm3 = xmm0[0,2,2,3]
        pshuflw $232, %xmm1, %xmm0      # xmm0 = xmm1[0,2,2,3,4,5,6,7]
        pshufhw $232, %xmm0, %xmm0      # xmm0 = xmm0[0,1,2,3,4,6,6,7]
        pshufd  $232, %xmm0, %xmm0      # xmm0 = xmm0[0,2,2,3]
        punpcklqdq      %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0]
        pshuflw $231, %xmm2, %xmm2      # xmm2 = xmm2[3,1,2,3,4,5,6,7]
        pshufhw $231, %xmm2, %xmm2      # xmm2 = xmm2[0,1,2,3,7,5,6,7]
        pshufd  $232, %xmm2, %xmm2      # xmm2 = xmm2[0,2,2,3]
        pshuflw $177, %xmm2, %xmm2      # xmm2 = xmm2[1,0,3,2,4,5,6,7]
        pshuflw $231, %xmm1, %xmm1      # xmm1 = xmm1[3,1,2,3,4,5,6,7]
        pshufhw $231, %xmm1, %xmm1      # xmm1 = xmm1[0,1,2,3,7,5,6,7]
        pshufd  $232, %xmm1, %xmm1      # xmm1 = xmm1[0,2,2,3]
        pshuflw $177, %xmm1, %xmm1      # xmm1 = xmm1[1,0,3,2,4,5,6,7]
        punpcklqdq      %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0]
        psubw   %xmm1, %xmm0
        retq</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>