<html>
<head>
<base href="https://bugs.llvm.org/">
</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 - [X86] [CodeGen] Compiler not using SHLD/SHRD instructions when doing double shift pattern combine for 16bit or 8bit arguments"
href="https://bugs.llvm.org/show_bug.cgi?id=35155">35155</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[X86] [CodeGen] Compiler not using SHLD/SHRD instructions when doing double shift pattern combine for 16bit or 8bit arguments
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</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>konstantin.belochapka@sony.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Consider the following code which implements double shift left:
uint64_t shld64(uint64_t a, uint64_t b, uint64_t shift)
{
return (a << shift) | (b >> (64 - shift));
}
uint32_t shld32(uint32_t a, uint32_t b, uint32_t shift)
{
return (a << shift) | (b >> (32 - shift));
}
uint16_t shld16(uint16_t a, uint16_t b, uint16_t shift)
{
return (a << shift) | (b >> (16 - shift));
}
uint8_t shld8(uint8_t a, uint8_t b, uint8_t shift)
{
return (a << shift) | (b >> (8 - shift));
}
With optimization enabled, clang produces the following assembler code:
shld64:
movl %edx, %ecx
shldq %cl, %rsi, %rdi
movq %rdi, %rax
retq
shld32:
movl %edx, %ecx
shldl %cl, %esi, %edi
movl %edi, %eax
retq
shld16:
movl %edx, %ecx
shll %cl, %edi
movl $16, %ecx
subl %edx, %ecx
shrl %cl, %esi
orl %edi, %esi
movl %esi, %eax
retq
shld8:
movl %edx, %ecx
shll %cl, %edi
movl $8, %ecx
subl %edx, %ecx
shrl %cl, %esi
orl %edi, %esi
movl %esi, %eax
retq
Obviously uint16_t type gets promoted to 32 bit and the backend code no longer
can recognize the double shift pattern.
Even with the integer promotion the generated code can be shorter, four
instruction against seven:
shld16:
shll $16, %esi
movl %edx, %ecx
shldl %cl, %esi, %edi
movl %edi, %eax
retq
shld8:
shll $24, %esi
movl %edx, %ecx
shldl %cl, %esi, %edi
movl %edi, %eax
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>