[LLVMbugs] [Bug 14593] New: 64-bit shift optimization

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Dec 12 22:56:29 PST 2012


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

             Bug #: 14593
           Summary: 64-bit shift optimization
           Product: clang
           Version: 3.1
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: nruslan_devel at yahoo.com
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Consider the following function for x86, 32-bit:

uint64_t right_shift(uint64_t val, unsigned int bits)
{
    return val >> (bits & 0x1F);
}

In this case I assume that 'bits' is going to be 0..31 and mask the value
expecting that compiler is smart enough to do double-shift without unnecessary
code for cases > 31 (e.g. value can be loaded directly to %cl since x86
hardware ignores upper bits anyway):

However, compiler does not generate an efficient version similar to shifting by
constant. The other weird thing is that 'shrdl' instruction is not used.

clang -Wall -O3 -m32 -S shift.c

    pushl   %esi
    movb    16(%esp), %ch
    movl    8(%esp), %esi
    movl    12(%esp), %edx
    movb    %ch, %cl
    shrl    %cl, %esi
    leal    (%edx,%edx), %eax
    movb    %ch, %cl
    andb    $31, %cl
    xorb    $31, %cl
    shll    %cl, %eax
    orl %esi, %eax
    movb    %ch, %cl
    shrl    %cl, %edx
    popl    %esi
    ret

Similar problem exists for x86_64 and 128 bit integers. By the way, is there
any other way to tell compiler that bits <= 31?

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list