Skip to content

Commit 9da3544

Browse files
committed
[GISel] Fold bitreverse(shl/srl(bitreverse(x),y)) -> srl/shl(x,y)
Sibling patch to llvm#89897
1 parent 5636eb8 commit 9da3544

File tree

2 files changed

+59
-99
lines changed

2 files changed

+59
-99
lines changed

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,28 @@ def reduce_shl_of_extend : GICombineRule<
325325
[{ return Helper.matchCombineShlOfExtend(*${mi}, ${matchinfo}); }]),
326326
(apply [{ Helper.applyCombineShlOfExtend(*${mi}, ${matchinfo}); }])>;
327327

328+
// Combine bitreverse(shl (bitreverse x), y)) -> (lshr x, y)
329+
def bitreverse_shl : GICombineRule<
330+
(defs root:$d),
331+
(match (G_BITREVERSE $rev, $val),
332+
(G_SHL $src, $rev, $amt):$mi,
333+
(G_BITREVERSE $d, $src),
334+
[{ return Helper.isLegalOrBeforeLegalizer({TargetOpcode::G_LSHR,
335+
{MRI.getType(${val}.getReg()),
336+
MRI.getType(${amt}.getReg())}}); }]),
337+
(apply (G_LSHR $d, $val, $amt))>;
338+
339+
// Combine bitreverse(lshr (bitreverse x), y)) -> (shl x, y)
340+
def bitreverse_lshr : GICombineRule<
341+
(defs root:$d, build_fn_matchinfo:$matchinfo),
342+
(match (G_BITREVERSE $rev, $val),
343+
(G_LSHR $src, $rev, $amt):$mi,
344+
(G_BITREVERSE $d, $src),
345+
[{ return Helper.isLegalOrBeforeLegalizer({TargetOpcode::G_SHL,
346+
{MRI.getType(${val}.getReg()),
347+
MRI.getType(${amt}.getReg())}}); }]),
348+
(apply (G_SHL $d, $val, $amt))>;
349+
328350
// Combine (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
329351
// Combine (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2)
330352
def commute_shift : GICombineRule<
@@ -1645,6 +1667,8 @@ def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend,
16451667

16461668
def phi_combines : GICombineGroup<[extend_through_phis]>;
16471669

1670+
def bitreverse_shift : GICombineGroup<[bitreverse_shl, bitreverse_lshr]>;
1671+
16481672
def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp,
16491673
match_selects]>;
16501674

@@ -1674,7 +1698,7 @@ def all_combines : GICombineGroup<[trivial_combines, vector_ops_combines,
16741698
unmerge_zext_to_zext, merge_unmerge, trunc_ext_fold, trunc_shift,
16751699
const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
16761700
shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine,
1677-
div_rem_to_divrem, funnel_shift_combines, commute_shift,
1701+
div_rem_to_divrem, funnel_shift_combines, bitreverse_shift, commute_shift,
16781702
form_bitfield_extract, constant_fold_binops, constant_fold_fma,
16791703
constant_fold_cast_op, fabs_fneg_fold,
16801704
intdiv_combines, mulh_combines, redundant_neg_operands,

llvm/test/CodeGen/AArch64/GlobalISel/combine-bitreverse-shift.ll

Lines changed: 34 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2-
; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s --check-prefixes=SDAG
3-
; RUN: llc < %s -mtriple=aarch64-unknown-unknown -global-isel | FileCheck %s --check-prefixes=GISEL
2+
; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
3+
; RUN: llc < %s -mtriple=aarch64-unknown-unknown -global-isel | FileCheck %s
44

55
; These tests can be optimised
66
; fold (bitreverse(srl (bitreverse c), x)) -> (shl c, x)
@@ -12,151 +12,87 @@ declare i32 @llvm.bitreverse.i32(i32)
1212
declare i64 @llvm.bitreverse.i64(i64)
1313

1414
define i8 @test_bitreverse_srli_bitreverse_i8(i8 %a) nounwind {
15-
; SDAG-LABEL: test_bitreverse_srli_bitreverse_i8:
16-
; SDAG: // %bb.0:
17-
; SDAG-NEXT: lsl w0, w0, #3
18-
; SDAG-NEXT: ret
19-
;
20-
; GISEL-LABEL: test_bitreverse_srli_bitreverse_i8:
21-
; GISEL: // %bb.0:
22-
; GISEL-NEXT: rbit w8, w0
23-
; GISEL-NEXT: lsr w8, w8, #24
24-
; GISEL-NEXT: lsr w8, w8, #3
25-
; GISEL-NEXT: rbit w8, w8
26-
; GISEL-NEXT: lsr w0, w8, #24
27-
; GISEL-NEXT: ret
15+
; CHECK-LABEL: test_bitreverse_srli_bitreverse_i8:
16+
; CHECK: // %bb.0:
17+
; CHECK-NEXT: lsl w0, w0, #3
18+
; CHECK-NEXT: ret
2819
%1 = call i8 @llvm.bitreverse.i8(i8 %a)
2920
%2 = lshr i8 %1, 3
3021
%3 = call i8 @llvm.bitreverse.i8(i8 %2)
3122
ret i8 %3
3223
}
3324

3425
define i16 @test_bitreverse_srli_bitreverse_i16(i16 %a) nounwind {
35-
; SDAG-LABEL: test_bitreverse_srli_bitreverse_i16:
36-
; SDAG: // %bb.0:
37-
; SDAG-NEXT: lsl w0, w0, #7
38-
; SDAG-NEXT: ret
39-
;
40-
; GISEL-LABEL: test_bitreverse_srli_bitreverse_i16:
41-
; GISEL: // %bb.0:
42-
; GISEL-NEXT: rbit w8, w0
43-
; GISEL-NEXT: lsr w8, w8, #16
44-
; GISEL-NEXT: lsr w8, w8, #7
45-
; GISEL-NEXT: rbit w8, w8
46-
; GISEL-NEXT: lsr w0, w8, #16
47-
; GISEL-NEXT: ret
26+
; CHECK-LABEL: test_bitreverse_srli_bitreverse_i16:
27+
; CHECK: // %bb.0:
28+
; CHECK-NEXT: lsl w0, w0, #7
29+
; CHECK-NEXT: ret
4830
%1 = call i16 @llvm.bitreverse.i16(i16 %a)
4931
%2 = lshr i16 %1, 7
5032
%3 = call i16 @llvm.bitreverse.i16(i16 %2)
5133
ret i16 %3
5234
}
5335

5436
define i32 @test_bitreverse_srli_bitreverse_i32(i32 %a) nounwind {
55-
; SDAG-LABEL: test_bitreverse_srli_bitreverse_i32:
56-
; SDAG: // %bb.0:
57-
; SDAG-NEXT: lsl w0, w0, #15
58-
; SDAG-NEXT: ret
59-
;
60-
; GISEL-LABEL: test_bitreverse_srli_bitreverse_i32:
61-
; GISEL: // %bb.0:
62-
; GISEL-NEXT: rbit w8, w0
63-
; GISEL-NEXT: lsr w8, w8, #15
64-
; GISEL-NEXT: rbit w0, w8
65-
; GISEL-NEXT: ret
37+
; CHECK-LABEL: test_bitreverse_srli_bitreverse_i32:
38+
; CHECK: // %bb.0:
39+
; CHECK-NEXT: lsl w0, w0, #15
40+
; CHECK-NEXT: ret
6641
%1 = call i32 @llvm.bitreverse.i32(i32 %a)
6742
%2 = lshr i32 %1, 15
6843
%3 = call i32 @llvm.bitreverse.i32(i32 %2)
6944
ret i32 %3
7045
}
7146

7247
define i64 @test_bitreverse_srli_bitreverse_i64(i64 %a) nounwind {
73-
; SDAG-LABEL: test_bitreverse_srli_bitreverse_i64:
74-
; SDAG: // %bb.0:
75-
; SDAG-NEXT: lsl x0, x0, #33
76-
; SDAG-NEXT: ret
77-
;
78-
; GISEL-LABEL: test_bitreverse_srli_bitreverse_i64:
79-
; GISEL: // %bb.0:
80-
; GISEL-NEXT: rbit x8, x0
81-
; GISEL-NEXT: lsr x8, x8, #33
82-
; GISEL-NEXT: rbit x0, x8
83-
; GISEL-NEXT: ret
48+
; CHECK-LABEL: test_bitreverse_srli_bitreverse_i64:
49+
; CHECK: // %bb.0:
50+
; CHECK-NEXT: lsl x0, x0, #33
51+
; CHECK-NEXT: ret
8452
%1 = call i64 @llvm.bitreverse.i64(i64 %a)
8553
%2 = lshr i64 %1, 33
8654
%3 = call i64 @llvm.bitreverse.i64(i64 %2)
8755
ret i64 %3
8856
}
8957

9058
define i8 @test_bitreverse_shli_bitreverse_i8(i8 %a) nounwind {
91-
; SDAG-LABEL: test_bitreverse_shli_bitreverse_i8:
92-
; SDAG: // %bb.0:
93-
; SDAG-NEXT: ubfx w0, w0, #3, #5
94-
; SDAG-NEXT: ret
95-
;
96-
; GISEL-LABEL: test_bitreverse_shli_bitreverse_i8:
97-
; GISEL: // %bb.0:
98-
; GISEL-NEXT: rbit w8, w0
99-
; GISEL-NEXT: lsr w8, w8, #24
100-
; GISEL-NEXT: lsl w8, w8, #3
101-
; GISEL-NEXT: rbit w8, w8
102-
; GISEL-NEXT: lsr w0, w8, #24
103-
; GISEL-NEXT: ret
59+
; CHECK-LABEL: test_bitreverse_shli_bitreverse_i8:
60+
; CHECK: // %bb.0:
61+
; CHECK-NEXT: ubfx w0, w0, #3, #5
62+
; CHECK-NEXT: ret
10463
%1 = call i8 @llvm.bitreverse.i8(i8 %a)
10564
%2 = shl i8 %1, 3
10665
%3 = call i8 @llvm.bitreverse.i8(i8 %2)
10766
ret i8 %3
10867
}
10968

11069
define i16 @test_bitreverse_shli_bitreverse_i16(i16 %a) nounwind {
111-
; SDAG-LABEL: test_bitreverse_shli_bitreverse_i16:
112-
; SDAG: // %bb.0:
113-
; SDAG-NEXT: ubfx w0, w0, #7, #9
114-
; SDAG-NEXT: ret
115-
;
116-
; GISEL-LABEL: test_bitreverse_shli_bitreverse_i16:
117-
; GISEL: // %bb.0:
118-
; GISEL-NEXT: rbit w8, w0
119-
; GISEL-NEXT: lsr w8, w8, #16
120-
; GISEL-NEXT: lsl w8, w8, #7
121-
; GISEL-NEXT: rbit w8, w8
122-
; GISEL-NEXT: lsr w0, w8, #16
123-
; GISEL-NEXT: ret
70+
; CHECK-LABEL: test_bitreverse_shli_bitreverse_i16:
71+
; CHECK: // %bb.0:
72+
; CHECK-NEXT: ubfx w0, w0, #7, #9
73+
; CHECK-NEXT: ret
12474
%1 = call i16 @llvm.bitreverse.i16(i16 %a)
12575
%2 = shl i16 %1, 7
12676
%3 = call i16 @llvm.bitreverse.i16(i16 %2)
12777
ret i16 %3
12878
}
12979

13080
define i32 @test_bitreverse_shli_bitreverse_i32(i32 %a) nounwind {
131-
; SDAG-LABEL: test_bitreverse_shli_bitreverse_i32:
132-
; SDAG: // %bb.0:
133-
; SDAG-NEXT: lsr w0, w0, #15
134-
; SDAG-NEXT: ret
135-
;
136-
; GISEL-LABEL: test_bitreverse_shli_bitreverse_i32:
137-
; GISEL: // %bb.0:
138-
; GISEL-NEXT: rbit w8, w0
139-
; GISEL-NEXT: lsl w8, w8, #15
140-
; GISEL-NEXT: rbit w0, w8
141-
; GISEL-NEXT: ret
81+
; CHECK-LABEL: test_bitreverse_shli_bitreverse_i32:
82+
; CHECK: // %bb.0:
83+
; CHECK-NEXT: lsr w0, w0, #15
84+
; CHECK-NEXT: ret
14285
%1 = call i32 @llvm.bitreverse.i32(i32 %a)
14386
%2 = shl i32 %1, 15
14487
%3 = call i32 @llvm.bitreverse.i32(i32 %2)
14588
ret i32 %3
14689
}
14790

14891
define i64 @test_bitreverse_shli_bitreverse_i64(i64 %a) nounwind {
149-
; SDAG-LABEL: test_bitreverse_shli_bitreverse_i64:
150-
; SDAG: // %bb.0:
151-
; SDAG-NEXT: lsr x0, x0, #33
152-
; SDAG-NEXT: ret
153-
;
154-
; GISEL-LABEL: test_bitreverse_shli_bitreverse_i64:
155-
; GISEL: // %bb.0:
156-
; GISEL-NEXT: rbit x8, x0
157-
; GISEL-NEXT: lsl x8, x8, #33
158-
; GISEL-NEXT: rbit x0, x8
159-
; GISEL-NEXT: ret
92+
; CHECK-LABEL: test_bitreverse_shli_bitreverse_i64:
93+
; CHECK: // %bb.0:
94+
; CHECK-NEXT: lsr x0, x0, #33
95+
; CHECK-NEXT: ret
16096
%1 = call i64 @llvm.bitreverse.i64(i64 %a)
16197
%2 = shl i64 %1, 33
16298
%3 = call i64 @llvm.bitreverse.i64(i64 %2)

0 commit comments

Comments
 (0)