xref: /llvm-project/llvm/test/CodeGen/ARM/combine-bitreverse.ll (revision 58c9ad9c85a579207fedab8815e4e071e3a13cbd)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv7m-none-eabi -mattr=v7 | FileCheck %s --check-prefixes=CHECK
3
4declare i16 @llvm.bswap.i16(i16) readnone
5declare i32 @llvm.bswap.i32(i32) readnone
6declare i32 @llvm.bitreverse.i32(i32) readnone
7
8define i32 @brev_and_lhs_brev32(i32 %a, i32 %b) #0 {
9; CHECK-LABEL: brev_and_lhs_brev32:
10; CHECK:       @ %bb.0:
11; CHECK-NEXT:    rbit r0, r0
12; CHECK-NEXT:    ands r0, r1
13; CHECK-NEXT:    rbit r0, r0
14; CHECK-NEXT:    bx lr
15  %1 = tail call i32 @llvm.bitreverse.i32(i32 %a)
16  %2 = and i32 %1, %b
17  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
18  ret i32 %3
19}
20
21define i32 @brev_or_lhs_brev32(i32 %a, i32 %b) #0 {
22; CHECK-LABEL: brev_or_lhs_brev32:
23; CHECK:       @ %bb.0:
24; CHECK-NEXT:    rbit r0, r0
25; CHECK-NEXT:    orrs r0, r1
26; CHECK-NEXT:    rbit r0, r0
27; CHECK-NEXT:    bx lr
28  %1 = tail call i32 @llvm.bitreverse.i32(i32 %a)
29  %2 = or i32 %1, %b
30  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
31  ret i32 %3
32}
33
34define i32 @brev_xor_rhs_brev32(i32 %a, i32 %b) #0 {
35; CHECK-LABEL: brev_xor_rhs_brev32:
36; CHECK:       @ %bb.0:
37; CHECK-NEXT:    rbit r1, r1
38; CHECK-NEXT:    eors r0, r1
39; CHECK-NEXT:    rbit r0, r0
40; CHECK-NEXT:    bx lr
41  %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
42  %2 = xor i32 %a, %1
43  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
44  ret i32 %3
45}
46
47define i32 @brev_and_all_operand_multiuse(i32 %a, i32 %b) #0 {
48; CHECK-LABEL: brev_and_all_operand_multiuse:
49; CHECK:       @ %bb.0:
50; CHECK-NEXT:    rbit r1, r1
51; CHECK-NEXT:    rbit r0, r0
52; CHECK-NEXT:    and.w r2, r0, r1
53; CHECK-NEXT:    rbit r2, r2
54; CHECK-NEXT:    muls r0, r2, r0
55; CHECK-NEXT:    muls r0, r1, r0
56; CHECK-NEXT:    bx lr
57  %1 = tail call i32 @llvm.bitreverse.i32(i32 %a)
58  %2 = tail call i32 @llvm.bitreverse.i32(i32 %b)
59  %3 = and i32 %1, %2
60  %4 = tail call i32 @llvm.bitreverse.i32(i32 %3)
61  %5 = mul i32 %1, %4 ;increase use of left bitreverse
62  %6 = mul i32 %2, %5 ;increase use of right bitreverse
63
64  ret i32 %6
65}
66
67; negative test
68define i32 @brev_and_rhs_brev32_multiuse1(i32 %a, i32 %b) #0 {
69; CHECK-LABEL: brev_and_rhs_brev32_multiuse1:
70; CHECK:       @ %bb.0:
71; CHECK-NEXT:    rbit r1, r1
72; CHECK-NEXT:    ands r0, r1
73; CHECK-NEXT:    rbit r1, r0
74; CHECK-NEXT:    muls r0, r1, r0
75; CHECK-NEXT:    bx lr
76  %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
77  %2 = and i32 %1, %a
78  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
79  %4 = mul i32 %2, %3 ;increase use of logical op
80  ret i32 %4
81}
82
83; negative test
84define i32 @brev_and_rhs_brev32_multiuse2(i32 %a, i32 %b) #0 {
85; CHECK-LABEL: brev_and_rhs_brev32_multiuse2:
86; CHECK:       @ %bb.0:
87; CHECK-NEXT:    rbit r1, r1
88; CHECK-NEXT:    ands r0, r1
89; CHECK-NEXT:    rbit r0, r0
90; CHECK-NEXT:    muls r0, r1, r0
91; CHECK-NEXT:    bx lr
92  %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
93  %2 = and i32 %1, %a
94  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
95  %4 = mul i32 %1, %3 ;increase use of inner bitreverse
96  ret i32 %4
97}
98
99; negative test
100define i32 @brev_xor_rhs_bs32(i32 %a, i32 %b) #0 {
101; CHECK-LABEL: brev_xor_rhs_bs32:
102; CHECK:       @ %bb.0:
103; CHECK-NEXT:    rev r1, r1
104; CHECK-NEXT:    eors r0, r1
105; CHECK-NEXT:    rbit r0, r0
106; CHECK-NEXT:    bx lr
107  %1 = tail call i32 @llvm.bswap.i32(i32 %b)
108  %2 = xor i32 %a, %1
109  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
110  ret i32 %3
111}
112
113