[llvm-bugs] [Bug 31714] New: Incorrect use of phsubw

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Jan 20 21:42:42 PST 2017


https://llvm.org/bugs/show_bug.cgi?id=31714

            Bug ID: 31714
           Summary: Incorrect use of phsubw
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: X86
          Assignee: unassignedbugs at nondot.org
          Reporter: andrew.b.adams at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170121/631e9521/attachment-0001.html>


More information about the llvm-bugs mailing list