[llvm-bugs] [Bug 35155] New: [X86] [CodeGen] Compiler not using SHLD/SHRD instructions when doing double shift pattern combine for 16bit or 8bit arguments

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Oct 31 17:02:04 PDT 2017


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

            Bug ID: 35155
           Summary: [X86] [CodeGen] Compiler not using SHLD/SHRD
                    instructions when doing double shift pattern combine
                    for 16bit or 8bit arguments
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: konstantin.belochapka at sony.com
                CC: llvm-bugs at lists.llvm.org

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

-- 
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/20171101/d9aeedaa/attachment.html>


More information about the llvm-bugs mailing list