<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>