Skip to content

Commit 24577bd

Browse files
committed
[RISCV] Add BSET/BCLR/BINV/BEXT patterns for riscv-experimental-rv64-legal-i32.
1 parent 6d1d7be commit 24577bd

File tree

2 files changed

+135
-62
lines changed

2 files changed

+135
-62
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,20 @@ def : Pat<(zext GPR:$src), (ADD_UW GPR:$src, (XLenVT X0))>;
851851
}
852852

853853
let Predicates = [HasStdExtZbs, IsRV64] in {
854+
def : Pat<(i32 (and (not (shiftop<shl> 1, (XLenVT GPR:$rs2))), GPR:$rs1)),
855+
(BCLR GPR:$rs1, GPR:$rs2)>;
856+
def : Pat<(i32 (and (rotl -2, (XLenVT GPR:$rs2)), GPR:$rs1)),
857+
(BCLR GPR:$rs1, GPR:$rs2)>;
858+
def : Pat<(i32 (or (shiftop<shl> 1, (XLenVT GPR:$rs2)), GPR:$rs1)),
859+
(BSET GPR:$rs1, GPR:$rs2)>;
860+
def : Pat<(i32 (xor (shiftop<shl> 1, (XLenVT GPR:$rs2)), GPR:$rs1)),
861+
(BINV GPR:$rs1, GPR:$rs2)>;
862+
def : Pat<(i32 (and (shiftop<srl> GPR:$rs1, (XLenVT GPR:$rs2)), 1)),
863+
(BEXT GPR:$rs1, GPR:$rs2)>;
864+
865+
def : Pat<(i32 (and (srl GPR:$rs1, uimm5:$shamt), (i32 1))),
866+
(BEXTI GPR:$rs1, uimm5:$shamt)>;
867+
854868
def : Pat<(i32 (and GPR:$rs1, BCLRMaski32:$mask)),
855869
(BCLRI GPR:$rs1, (i64 (BCLRXForm $mask)))>;
856870
def : Pat<(i32 (or GPR:$rs1, SingleBitSetMaski32:$mask)),

llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbs.ll

Lines changed: 121 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@
55
; RUN: -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64ZBS
66

77
define signext i32 @bclr_i32(i32 signext %a, i32 signext %b) nounwind {
8-
; CHECK-LABEL: bclr_i32:
9-
; CHECK: # %bb.0:
10-
; CHECK-NEXT: li a2, 1
11-
; CHECK-NEXT: sllw a1, a2, a1
12-
; CHECK-NEXT: not a1, a1
13-
; CHECK-NEXT: and a0, a1, a0
14-
; CHECK-NEXT: ret
8+
; RV64I-LABEL: bclr_i32:
9+
; RV64I: # %bb.0:
10+
; RV64I-NEXT: li a2, 1
11+
; RV64I-NEXT: sllw a1, a2, a1
12+
; RV64I-NEXT: not a1, a1
13+
; RV64I-NEXT: and a0, a1, a0
14+
; RV64I-NEXT: ret
15+
;
16+
; RV64ZBS-LABEL: bclr_i32:
17+
; RV64ZBS: # %bb.0:
18+
; RV64ZBS-NEXT: andi a1, a1, 31
19+
; RV64ZBS-NEXT: bclr a0, a0, a1
20+
; RV64ZBS-NEXT: sext.w a0, a0
21+
; RV64ZBS-NEXT: ret
1522
%and = and i32 %b, 31
1623
%shl = shl nuw i32 1, %and
1724
%neg = xor i32 %shl, -1
@@ -20,28 +27,41 @@ define signext i32 @bclr_i32(i32 signext %a, i32 signext %b) nounwind {
2027
}
2128

2229
define signext i32 @bclr_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
23-
; CHECK-LABEL: bclr_i32_no_mask:
24-
; CHECK: # %bb.0:
25-
; CHECK-NEXT: li a2, 1
26-
; CHECK-NEXT: sllw a1, a2, a1
27-
; CHECK-NEXT: not a1, a1
28-
; CHECK-NEXT: and a0, a1, a0
29-
; CHECK-NEXT: ret
30+
; RV64I-LABEL: bclr_i32_no_mask:
31+
; RV64I: # %bb.0:
32+
; RV64I-NEXT: li a2, 1
33+
; RV64I-NEXT: sllw a1, a2, a1
34+
; RV64I-NEXT: not a1, a1
35+
; RV64I-NEXT: and a0, a1, a0
36+
; RV64I-NEXT: ret
37+
;
38+
; RV64ZBS-LABEL: bclr_i32_no_mask:
39+
; RV64ZBS: # %bb.0:
40+
; RV64ZBS-NEXT: bclr a0, a0, a1
41+
; RV64ZBS-NEXT: sext.w a0, a0
42+
; RV64ZBS-NEXT: ret
3043
%shl = shl i32 1, %b
3144
%neg = xor i32 %shl, -1
3245
%and1 = and i32 %neg, %a
3346
ret i32 %and1
3447
}
3548

3649
define signext i32 @bclr_i32_load(ptr %p, i32 signext %b) nounwind {
37-
; CHECK-LABEL: bclr_i32_load:
38-
; CHECK: # %bb.0:
39-
; CHECK-NEXT: lw a0, 0(a0)
40-
; CHECK-NEXT: li a2, 1
41-
; CHECK-NEXT: sllw a1, a2, a1
42-
; CHECK-NEXT: not a1, a1
43-
; CHECK-NEXT: and a0, a1, a0
44-
; CHECK-NEXT: ret
50+
; RV64I-LABEL: bclr_i32_load:
51+
; RV64I: # %bb.0:
52+
; RV64I-NEXT: lw a0, 0(a0)
53+
; RV64I-NEXT: li a2, 1
54+
; RV64I-NEXT: sllw a1, a2, a1
55+
; RV64I-NEXT: not a1, a1
56+
; RV64I-NEXT: and a0, a1, a0
57+
; RV64I-NEXT: ret
58+
;
59+
; RV64ZBS-LABEL: bclr_i32_load:
60+
; RV64ZBS: # %bb.0:
61+
; RV64ZBS-NEXT: lw a0, 0(a0)
62+
; RV64ZBS-NEXT: bclr a0, a0, a1
63+
; RV64ZBS-NEXT: sext.w a0, a0
64+
; RV64ZBS-NEXT: ret
4565
%a = load i32, ptr %p
4666
%shl = shl i32 1, %b
4767
%neg = xor i32 %shl, -1
@@ -89,38 +109,58 @@ define i64 @bclr_i64_no_mask(i64 %a, i64 %b) nounwind {
89109
}
90110

91111
define signext i32 @bset_i32(i32 signext %a, i32 signext %b) nounwind {
92-
; CHECK-LABEL: bset_i32:
93-
; CHECK: # %bb.0:
94-
; CHECK-NEXT: li a2, 1
95-
; CHECK-NEXT: sllw a1, a2, a1
96-
; CHECK-NEXT: or a0, a1, a0
97-
; CHECK-NEXT: ret
112+
; RV64I-LABEL: bset_i32:
113+
; RV64I: # %bb.0:
114+
; RV64I-NEXT: li a2, 1
115+
; RV64I-NEXT: sllw a1, a2, a1
116+
; RV64I-NEXT: or a0, a1, a0
117+
; RV64I-NEXT: ret
118+
;
119+
; RV64ZBS-LABEL: bset_i32:
120+
; RV64ZBS: # %bb.0:
121+
; RV64ZBS-NEXT: andi a1, a1, 31
122+
; RV64ZBS-NEXT: bset a0, a0, a1
123+
; RV64ZBS-NEXT: sext.w a0, a0
124+
; RV64ZBS-NEXT: ret
98125
%and = and i32 %b, 31
99126
%shl = shl nuw i32 1, %and
100127
%or = or i32 %shl, %a
101128
ret i32 %or
102129
}
103130

104131
define signext i32 @bset_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
105-
; CHECK-LABEL: bset_i32_no_mask:
106-
; CHECK: # %bb.0:
107-
; CHECK-NEXT: li a2, 1
108-
; CHECK-NEXT: sllw a1, a2, a1
109-
; CHECK-NEXT: or a0, a1, a0
110-
; CHECK-NEXT: ret
132+
; RV64I-LABEL: bset_i32_no_mask:
133+
; RV64I: # %bb.0:
134+
; RV64I-NEXT: li a2, 1
135+
; RV64I-NEXT: sllw a1, a2, a1
136+
; RV64I-NEXT: or a0, a1, a0
137+
; RV64I-NEXT: ret
138+
;
139+
; RV64ZBS-LABEL: bset_i32_no_mask:
140+
; RV64ZBS: # %bb.0:
141+
; RV64ZBS-NEXT: bset a0, a0, a1
142+
; RV64ZBS-NEXT: sext.w a0, a0
143+
; RV64ZBS-NEXT: ret
111144
%shl = shl i32 1, %b
112145
%or = or i32 %shl, %a
113146
ret i32 %or
114147
}
115148

116149
define signext i32 @bset_i32_load(ptr %p, i32 signext %b) nounwind {
117-
; CHECK-LABEL: bset_i32_load:
118-
; CHECK: # %bb.0:
119-
; CHECK-NEXT: lw a0, 0(a0)
120-
; CHECK-NEXT: li a2, 1
121-
; CHECK-NEXT: sllw a1, a2, a1
122-
; CHECK-NEXT: or a0, a1, a0
123-
; CHECK-NEXT: ret
150+
; RV64I-LABEL: bset_i32_load:
151+
; RV64I: # %bb.0:
152+
; RV64I-NEXT: lw a0, 0(a0)
153+
; RV64I-NEXT: li a2, 1
154+
; RV64I-NEXT: sllw a1, a2, a1
155+
; RV64I-NEXT: or a0, a1, a0
156+
; RV64I-NEXT: ret
157+
;
158+
; RV64ZBS-LABEL: bset_i32_load:
159+
; RV64ZBS: # %bb.0:
160+
; RV64ZBS-NEXT: lw a0, 0(a0)
161+
; RV64ZBS-NEXT: bset a0, a0, a1
162+
; RV64ZBS-NEXT: sext.w a0, a0
163+
; RV64ZBS-NEXT: ret
124164
%a = load i32, ptr %p
125165
%shl = shl i32 1, %b
126166
%or = or i32 %shl, %a
@@ -190,38 +230,58 @@ define signext i64 @bset_i64_zero(i64 signext %a) nounwind {
190230
}
191231

192232
define signext i32 @binv_i32(i32 signext %a, i32 signext %b) nounwind {
193-
; CHECK-LABEL: binv_i32:
194-
; CHECK: # %bb.0:
195-
; CHECK-NEXT: li a2, 1
196-
; CHECK-NEXT: sllw a1, a2, a1
197-
; CHECK-NEXT: xor a0, a1, a0
198-
; CHECK-NEXT: ret
233+
; RV64I-LABEL: binv_i32:
234+
; RV64I: # %bb.0:
235+
; RV64I-NEXT: li a2, 1
236+
; RV64I-NEXT: sllw a1, a2, a1
237+
; RV64I-NEXT: xor a0, a1, a0
238+
; RV64I-NEXT: ret
239+
;
240+
; RV64ZBS-LABEL: binv_i32:
241+
; RV64ZBS: # %bb.0:
242+
; RV64ZBS-NEXT: andi a1, a1, 31
243+
; RV64ZBS-NEXT: binv a0, a0, a1
244+
; RV64ZBS-NEXT: sext.w a0, a0
245+
; RV64ZBS-NEXT: ret
199246
%and = and i32 %b, 31
200247
%shl = shl nuw i32 1, %and
201248
%xor = xor i32 %shl, %a
202249
ret i32 %xor
203250
}
204251

205252
define signext i32 @binv_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
206-
; CHECK-LABEL: binv_i32_no_mask:
207-
; CHECK: # %bb.0:
208-
; CHECK-NEXT: li a2, 1
209-
; CHECK-NEXT: sllw a1, a2, a1
210-
; CHECK-NEXT: xor a0, a1, a0
211-
; CHECK-NEXT: ret
253+
; RV64I-LABEL: binv_i32_no_mask:
254+
; RV64I: # %bb.0:
255+
; RV64I-NEXT: li a2, 1
256+
; RV64I-NEXT: sllw a1, a2, a1
257+
; RV64I-NEXT: xor a0, a1, a0
258+
; RV64I-NEXT: ret
259+
;
260+
; RV64ZBS-LABEL: binv_i32_no_mask:
261+
; RV64ZBS: # %bb.0:
262+
; RV64ZBS-NEXT: binv a0, a0, a1
263+
; RV64ZBS-NEXT: sext.w a0, a0
264+
; RV64ZBS-NEXT: ret
212265
%shl = shl i32 1, %b
213266
%xor = xor i32 %shl, %a
214267
ret i32 %xor
215268
}
216269

217270
define signext i32 @binv_i32_load(ptr %p, i32 signext %b) nounwind {
218-
; CHECK-LABEL: binv_i32_load:
219-
; CHECK: # %bb.0:
220-
; CHECK-NEXT: lw a0, 0(a0)
221-
; CHECK-NEXT: li a2, 1
222-
; CHECK-NEXT: sllw a1, a2, a1
223-
; CHECK-NEXT: xor a0, a1, a0
224-
; CHECK-NEXT: ret
271+
; RV64I-LABEL: binv_i32_load:
272+
; RV64I: # %bb.0:
273+
; RV64I-NEXT: lw a0, 0(a0)
274+
; RV64I-NEXT: li a2, 1
275+
; RV64I-NEXT: sllw a1, a2, a1
276+
; RV64I-NEXT: xor a0, a1, a0
277+
; RV64I-NEXT: ret
278+
;
279+
; RV64ZBS-LABEL: binv_i32_load:
280+
; RV64ZBS: # %bb.0:
281+
; RV64ZBS-NEXT: lw a0, 0(a0)
282+
; RV64ZBS-NEXT: binv a0, a0, a1
283+
; RV64ZBS-NEXT: sext.w a0, a0
284+
; RV64ZBS-NEXT: ret
225285
%a = load i32, ptr %p
226286
%shl = shl i32 1, %b
227287
%xor = xor i32 %shl, %a
@@ -377,8 +437,7 @@ define signext i32 @bexti_i32(i32 signext %a) nounwind {
377437
;
378438
; RV64ZBS-LABEL: bexti_i32:
379439
; RV64ZBS: # %bb.0:
380-
; RV64ZBS-NEXT: srliw a0, a0, 5
381-
; RV64ZBS-NEXT: andi a0, a0, 1
440+
; RV64ZBS-NEXT: bexti a0, a0, 5
382441
; RV64ZBS-NEXT: ret
383442
%shr = lshr i32 %a, 5
384443
%and = and i32 %shr, 1

0 commit comments

Comments
 (0)