[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