<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Canonicalization of rbit for ARMv8 64 bit fails"
   href="https://llvm.org/bugs/show_bug.cgi?id=31803">31803</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Canonicalization of rbit for ARMv8 64 bit fails
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </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>normal
          </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>gonzalobg88@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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",@progbits
    .globl    rbit_u64
    .p2align    2
    .type    rbit_u64,@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","",@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.</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>