[LLVMbugs] [Bug 20605] New: clang should optimize common patterns to portably read big/little-endian data

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Aug 9 13:14:50 PDT 2014


http://llvm.org/bugs/show_bug.cgi?id=20605

            Bug ID: 20605
           Summary: clang should optimize common patterns to portably read
                    big/little-endian data
           Product: new-bugs
           Version: 3.4
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: fuzxxl at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

A common idiom to portably read integers with well-defined endianess from a
buffer is code like this:

    uint32_t le32read(uint8_t buf[static 4]) {
            return ((uint32_t)buf[0]
                | (uint32_t)buf[1] << 8
                | (uint32_t)buf[2] << 16
                | (uint32_t)buf[3] << 24);
    }

    uint32_t be32read(uint8_t buf[static 4]) {
            return ((uint32_t)buf[0]
                | (uint32_t)buf[1] << 24
                | (uint32_t)buf[2] << 16
                | (uint32_t)buf[3] << 8);
    }

On architectures where unaligned reads are legal (e.g. amd64), the above code
could be compiled into something like this:

    le32read:
            mov (%rdi), %eax
            ret

    be32read:
            mov (%rdi), %eax
            bswap %eax
            ret

Yet clang seems to not optimize this kind of code well. Here is the assembly
clang generates (cleaned up):

    le32read:
            movzbl  (%rdi), %eax
            movzbl  1(%rdi), %ecx
            shll    $8, %ecx
            orl     %eax, %ecx
            movzbl  2(%rdi), %edx
            shll    $16, %edx
            orl     %ecx, %edx
            movzbl  3(%rdi), %eax
            shll    $24, %eax
            orl     %edx, %eax
            ret

    be32read:
            movzbl  (%rdi), %eax
            shll    $24, %eax
            movzbl  1(%rdi), %ecx
            shll    $16, %ecx
            orl     %eax, %ecx
            movzbl  2(%rdi), %edx
            shll    $8, %edx
            orl     %ecx, %edx
            movzbl  3(%rdi), %eax
            orl     %edx, %eax
            ret

It would be great if clang was capable of optimizing this kind of pattern as it
pops up continuously and is one of the few (the only?) way to (de)serialise
data with known endianess in a portable fashion.

-- 
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/20140809/c2542658/attachment.html>


More information about the llvm-bugs mailing list