<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>