[llvm-bugs] [Bug 31803] New: Canonicalization of rbit for ARMv8 64 bit fails

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Jan 30 11:21:47 PST 2017


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

            Bug ID: 31803
           Summary: Canonicalization of rbit for ARMv8 64 bit fails
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: gonzalobg88 at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

I expect this rust code to properly lower to just lower to rbit for 64 bit
integers in ARMv8, but the assembly generated by LLVM is awful.

pub fn rbit<T: Int>(y: T) -> T {
    let mut x = y;
    let width = T::byte_size();
    let k = T::bit_size() - T::from_u32(1);

    {
        let mut up0 = |i, l, r| if k & i > T::from_u32(0) {
            x = ((x & l) << i) | ((x & r) >> i);
        };

        up0(T::from_u32(1),
            T::from_u64(0x5555555555555555u64),
            T::from_u64(0xAAAAAAAAAAAAAAAAu64));
        up0(T::from_u32(2),
            T::from_u64(0x3333333333333333u64),
            T::from_u64(0xCCCCCCCCCCCCCCCCu64));
        up0(T::from_u32(4),
            T::from_u64(0x0F0F0F0F0F0F0F0Fu64),
            T::from_u64(0xF0F0F0F0F0F0F0F0u64));
    }
    {
        let mut up1 = |i, s, l, r| if width > i && (k & s > T::from_u32(0)) {
            x = ((x & l) << s) | ((x & r) >> s);
        };

        up1(T::from_u32(1),
            T::from_u32(8),
            T::from_u64(0x00FF00FF00FF00FFu64),
            T::from_u64(0xFF00FF00FF00FF00u64));
        up1(T::from_u32(2),
            T::from_u32(16),
            T::from_u64(0x0000FFFF0000FFFFu64),
            T::from_u64(0xFFFF0000FFFF0000u64));
        up1(T::from_u32(4),
            T::from_u32(32),
            T::from_u64(0x00000000FFFFFFFFu64),
            T::from_u64(0xFFFFFFFF00000000u64));
    }
    x
}

I can try to provide the llvm ir but this is the assembly I get:

    .text
    .file    "armv8_none_rbit.cgu-0.rs"
    .section    .text.rbit_u64,"ax", at progbits
    .globl    rbit_u64
    .p2align    2
    .type    rbit_u64, at function
rbit_u64:
    lsl    x8, x0, #1
    lsr    x9, x0, #1
    and    x8, x8, #0xaaaaaaaaaaaaaaaa
    and    x9, x9, #0x5555555555555555
    orr        x8, x9, x8
    lsl    x9, x8, #2
    lsr    x8, x8, #2
    and    x9, x9, #0xcccccccccccccccc
    and    x8, x8, #0x3333333333333333
    orr        x8, x8, x9
    lsl    x9, x8, #4
    lsr    x8, x8, #4
    and    x9, x9, #0xf0f0f0f0f0f0f0f0
    and    x8, x8, #0xf0f0f0f0f0f0f0f
    orr        x8, x8, x9
    lsl    x9, x8, #8
    lsr    x8, x8, #8
    and    x9, x9, #0xff00ff00ff00ff00
    and    x8, x8, #0xff00ff00ff00ff
    orr        x8, x8, x9
    lsl    x9, x8, #16
    lsr    x8, x8, #16
    and    x9, x9, #0xffff0000ffff0000
    and    x8, x8, #0xffff0000ffff
    orr        x8, x8, x9
    ror     x0, x8, #32
    ret
.Lfunc_end0:
    .size    rbit_u64, .Lfunc_end0-rbit_u64


    .section    ".note.GNU-stack","", at progbits


I know that there is an llvm.bitreverse intrinsic but since there is a lot of
existing software that predates the intrinsic maybe we should try to do better
here.

-- 
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/20170130/25337964/attachment.html>


More information about the llvm-bugs mailing list