Skip to content

Commit a1094b2

Browse files
committed
[RISCV][SelDAG] and x (sub 0, y) -> andn x y
1 parent 884b79a commit a1094b2

File tree

5 files changed

+362
-116
lines changed

5 files changed

+362
-116
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;
483483

484484
let Predicates = [HasStdExtZbbOrZbkb] in {
485485
def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
486+
def : Pat<(XLenVT (and GPR:$rs1, (sub 0, GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
486487
def : Pat<(XLenVT (or GPR:$rs1, (not GPR:$rs2))), (ORN GPR:$rs1, GPR:$rs2)>;
487488
def : Pat<(XLenVT (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
488489

llvm/test/CodeGen/RISCV/GlobalISel/rv32zbb-zbkb.ll

Lines changed: 234 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ define i32 @andn_i32(i32 %a, i32 %b) nounwind {
2222
ret i32 %and
2323
}
2424

25+
define i32 @andn_i32_from_sub(i32 %a, i32 %b) nounwind {
26+
; RV32I-LABEL: andn_i32_from_sub:
27+
; RV32I: # %bb.0:
28+
; RV32I-NEXT: neg a1, a1
29+
; RV32I-NEXT: and a0, a1, a0
30+
; RV32I-NEXT: ret
31+
;
32+
; RV32ZBB-ZBKB-LABEL: andn_i32_from_sub:
33+
; RV32ZBB-ZBKB: # %bb.0:
34+
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
35+
; RV32ZBB-ZBKB-NEXT: ret
36+
%neg = sub i32 0, %b
37+
%and = and i32 %neg, %a
38+
ret i32 %and
39+
}
40+
2541
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
2642
; RV32I-LABEL: andn_i64:
2743
; RV32I: # %bb.0:
@@ -41,6 +57,30 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
4157
ret i64 %and
4258
}
4359

60+
define i64 @andn_i64_from_sub(i64 %a, i64 %b) nounwind {
61+
; RV32I-LABEL: andn_i64_from_sub:
62+
; RV32I: # %bb.0:
63+
; RV32I-NEXT: neg a4, a2
64+
; RV32I-NEXT: snez a2, a2
65+
; RV32I-NEXT: neg a3, a3
66+
; RV32I-NEXT: sub a3, a3, a2
67+
; RV32I-NEXT: and a0, a4, a0
68+
; RV32I-NEXT: and a1, a3, a1
69+
; RV32I-NEXT: ret
70+
;
71+
; RV32ZBB-ZBKB-LABEL: andn_i64_from_sub:
72+
; RV32ZBB-ZBKB: # %bb.0:
73+
; RV32ZBB-ZBKB-NEXT: snez a4, a2
74+
; RV32ZBB-ZBKB-NEXT: neg a3, a3
75+
; RV32ZBB-ZBKB-NEXT: sub a3, a3, a4
76+
; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
77+
; RV32ZBB-ZBKB-NEXT: and a1, a3, a1
78+
; RV32ZBB-ZBKB-NEXT: ret
79+
%neg = sub i64 0, %b
80+
%and = and i64 %neg, %a
81+
ret i64 %and
82+
}
83+
4484
define i32 @orn_i32(i32 %a, i32 %b) nounwind {
4585
; RV32I-LABEL: orn_i32:
4686
; RV32I: # %bb.0:
@@ -136,53 +176,102 @@ define i32 @rol_i32(i32 %a, i32 %b) nounwind {
136176
declare i64 @llvm.fshl.i64(i64, i64, i64)
137177

138178
define i64 @rol_i64(i64 %a, i64 %b) nounwind {
139-
; CHECK-LABEL: rol_i64:
140-
; CHECK: # %bb.0:
141-
; CHECK-NEXT: andi a6, a2, 63
142-
; CHECK-NEXT: li a4, 32
143-
; CHECK-NEXT: bltu a6, a4, .LBB7_2
144-
; CHECK-NEXT: # %bb.1:
145-
; CHECK-NEXT: li a3, 0
146-
; CHECK-NEXT: sll a7, a0, a6
147-
; CHECK-NEXT: j .LBB7_3
148-
; CHECK-NEXT: .LBB7_2:
149-
; CHECK-NEXT: sll a3, a0, a2
150-
; CHECK-NEXT: neg a5, a6
151-
; CHECK-NEXT: srl a5, a0, a5
152-
; CHECK-NEXT: sll a7, a1, a2
153-
; CHECK-NEXT: or a7, a5, a7
154-
; CHECK-NEXT: .LBB7_3:
155-
; CHECK-NEXT: neg a5, a2
156-
; CHECK-NEXT: mv a2, a1
157-
; CHECK-NEXT: beqz a6, .LBB7_5
158-
; CHECK-NEXT: # %bb.4:
159-
; CHECK-NEXT: mv a2, a7
160-
; CHECK-NEXT: .LBB7_5:
161-
; CHECK-NEXT: andi a6, a5, 63
162-
; CHECK-NEXT: bltu a6, a4, .LBB7_7
163-
; CHECK-NEXT: # %bb.6:
164-
; CHECK-NEXT: srl a7, a1, a6
165-
; CHECK-NEXT: bnez a6, .LBB7_8
166-
; CHECK-NEXT: j .LBB7_9
167-
; CHECK-NEXT: .LBB7_7:
168-
; CHECK-NEXT: srl a7, a0, a5
169-
; CHECK-NEXT: neg t0, a6
170-
; CHECK-NEXT: sll t0, a1, t0
171-
; CHECK-NEXT: or a7, a7, t0
172-
; CHECK-NEXT: beqz a6, .LBB7_9
173-
; CHECK-NEXT: .LBB7_8:
174-
; CHECK-NEXT: mv a0, a7
175-
; CHECK-NEXT: .LBB7_9:
176-
; CHECK-NEXT: bltu a6, a4, .LBB7_11
177-
; CHECK-NEXT: # %bb.10:
178-
; CHECK-NEXT: li a1, 0
179-
; CHECK-NEXT: j .LBB7_12
180-
; CHECK-NEXT: .LBB7_11:
181-
; CHECK-NEXT: srl a1, a1, a5
182-
; CHECK-NEXT: .LBB7_12:
183-
; CHECK-NEXT: or a0, a3, a0
184-
; CHECK-NEXT: or a1, a2, a1
185-
; CHECK-NEXT: ret
179+
; RV32I-LABEL: rol_i64:
180+
; RV32I: # %bb.0:
181+
; RV32I-NEXT: andi a6, a2, 63
182+
; RV32I-NEXT: li a4, 32
183+
; RV32I-NEXT: bltu a6, a4, .LBB9_2
184+
; RV32I-NEXT: # %bb.1:
185+
; RV32I-NEXT: li a3, 0
186+
; RV32I-NEXT: sll a7, a0, a6
187+
; RV32I-NEXT: j .LBB9_3
188+
; RV32I-NEXT: .LBB9_2:
189+
; RV32I-NEXT: sll a3, a0, a2
190+
; RV32I-NEXT: neg a5, a6
191+
; RV32I-NEXT: srl a5, a0, a5
192+
; RV32I-NEXT: sll a7, a1, a2
193+
; RV32I-NEXT: or a7, a5, a7
194+
; RV32I-NEXT: .LBB9_3:
195+
; RV32I-NEXT: neg a5, a2
196+
; RV32I-NEXT: mv a2, a1
197+
; RV32I-NEXT: beqz a6, .LBB9_5
198+
; RV32I-NEXT: # %bb.4:
199+
; RV32I-NEXT: mv a2, a7
200+
; RV32I-NEXT: .LBB9_5:
201+
; RV32I-NEXT: andi a6, a5, 63
202+
; RV32I-NEXT: bltu a6, a4, .LBB9_7
203+
; RV32I-NEXT: # %bb.6:
204+
; RV32I-NEXT: srl a7, a1, a6
205+
; RV32I-NEXT: bnez a6, .LBB9_8
206+
; RV32I-NEXT: j .LBB9_9
207+
; RV32I-NEXT: .LBB9_7:
208+
; RV32I-NEXT: srl a7, a0, a5
209+
; RV32I-NEXT: neg t0, a6
210+
; RV32I-NEXT: sll t0, a1, t0
211+
; RV32I-NEXT: or a7, a7, t0
212+
; RV32I-NEXT: beqz a6, .LBB9_9
213+
; RV32I-NEXT: .LBB9_8:
214+
; RV32I-NEXT: mv a0, a7
215+
; RV32I-NEXT: .LBB9_9:
216+
; RV32I-NEXT: bltu a6, a4, .LBB9_11
217+
; RV32I-NEXT: # %bb.10:
218+
; RV32I-NEXT: li a1, 0
219+
; RV32I-NEXT: j .LBB9_12
220+
; RV32I-NEXT: .LBB9_11:
221+
; RV32I-NEXT: srl a1, a1, a5
222+
; RV32I-NEXT: .LBB9_12:
223+
; RV32I-NEXT: or a0, a3, a0
224+
; RV32I-NEXT: or a1, a2, a1
225+
; RV32I-NEXT: ret
226+
;
227+
; RV32ZBB-ZBKB-LABEL: rol_i64:
228+
; RV32ZBB-ZBKB: # %bb.0:
229+
; RV32ZBB-ZBKB-NEXT: andi a6, a2, 63
230+
; RV32ZBB-ZBKB-NEXT: li a4, 32
231+
; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_2
232+
; RV32ZBB-ZBKB-NEXT: # %bb.1:
233+
; RV32ZBB-ZBKB-NEXT: li a3, 0
234+
; RV32ZBB-ZBKB-NEXT: sll a7, a0, a6
235+
; RV32ZBB-ZBKB-NEXT: j .LBB9_3
236+
; RV32ZBB-ZBKB-NEXT: .LBB9_2:
237+
; RV32ZBB-ZBKB-NEXT: sll a3, a0, a2
238+
; RV32ZBB-ZBKB-NEXT: neg a5, a6
239+
; RV32ZBB-ZBKB-NEXT: srl a5, a0, a5
240+
; RV32ZBB-ZBKB-NEXT: sll a7, a1, a2
241+
; RV32ZBB-ZBKB-NEXT: or a7, a5, a7
242+
; RV32ZBB-ZBKB-NEXT: .LBB9_3:
243+
; RV32ZBB-ZBKB-NEXT: li t0, 63
244+
; RV32ZBB-ZBKB-NEXT: mv a5, a1
245+
; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_5
246+
; RV32ZBB-ZBKB-NEXT: # %bb.4:
247+
; RV32ZBB-ZBKB-NEXT: mv a5, a7
248+
; RV32ZBB-ZBKB-NEXT: .LBB9_5:
249+
; RV32ZBB-ZBKB-NEXT: andn a6, t0, a2
250+
; RV32ZBB-ZBKB-NEXT: neg a2, a2
251+
; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_7
252+
; RV32ZBB-ZBKB-NEXT: # %bb.6:
253+
; RV32ZBB-ZBKB-NEXT: srl a7, a1, a6
254+
; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB9_8
255+
; RV32ZBB-ZBKB-NEXT: j .LBB9_9
256+
; RV32ZBB-ZBKB-NEXT: .LBB9_7:
257+
; RV32ZBB-ZBKB-NEXT: srl a7, a0, a2
258+
; RV32ZBB-ZBKB-NEXT: neg t0, a6
259+
; RV32ZBB-ZBKB-NEXT: sll t0, a1, t0
260+
; RV32ZBB-ZBKB-NEXT: or a7, a7, t0
261+
; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB9_9
262+
; RV32ZBB-ZBKB-NEXT: .LBB9_8:
263+
; RV32ZBB-ZBKB-NEXT: mv a0, a7
264+
; RV32ZBB-ZBKB-NEXT: .LBB9_9:
265+
; RV32ZBB-ZBKB-NEXT: bltu a6, a4, .LBB9_11
266+
; RV32ZBB-ZBKB-NEXT: # %bb.10:
267+
; RV32ZBB-ZBKB-NEXT: li a1, 0
268+
; RV32ZBB-ZBKB-NEXT: j .LBB9_12
269+
; RV32ZBB-ZBKB-NEXT: .LBB9_11:
270+
; RV32ZBB-ZBKB-NEXT: srl a1, a1, a2
271+
; RV32ZBB-ZBKB-NEXT: .LBB9_12:
272+
; RV32ZBB-ZBKB-NEXT: or a0, a3, a0
273+
; RV32ZBB-ZBKB-NEXT: or a1, a5, a1
274+
; RV32ZBB-ZBKB-NEXT: ret
186275
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
187276
ret i64 %or
188277
}
@@ -212,54 +301,104 @@ define i32 @ror_i32(i32 %a, i32 %b) nounwind {
212301
declare i64 @llvm.fshr.i64(i64, i64, i64)
213302

214303
define i64 @ror_i64(i64 %a, i64 %b) nounwind {
215-
; CHECK-LABEL: ror_i64:
216-
; CHECK: # %bb.0:
217-
; CHECK-NEXT: andi a5, a2, 63
218-
; CHECK-NEXT: li a4, 32
219-
; CHECK-NEXT: bltu a5, a4, .LBB9_2
220-
; CHECK-NEXT: # %bb.1:
221-
; CHECK-NEXT: srl a6, a1, a5
222-
; CHECK-NEXT: mv a3, a0
223-
; CHECK-NEXT: bnez a5, .LBB9_3
224-
; CHECK-NEXT: j .LBB9_4
225-
; CHECK-NEXT: .LBB9_2:
226-
; CHECK-NEXT: srl a3, a0, a2
227-
; CHECK-NEXT: neg a6, a5
228-
; CHECK-NEXT: sll a6, a1, a6
229-
; CHECK-NEXT: or a6, a3, a6
230-
; CHECK-NEXT: mv a3, a0
231-
; CHECK-NEXT: beqz a5, .LBB9_4
232-
; CHECK-NEXT: .LBB9_3:
233-
; CHECK-NEXT: mv a3, a6
234-
; CHECK-NEXT: .LBB9_4:
235-
; CHECK-NEXT: neg a6, a2
236-
; CHECK-NEXT: bltu a5, a4, .LBB9_7
237-
; CHECK-NEXT: # %bb.5:
238-
; CHECK-NEXT: li a2, 0
239-
; CHECK-NEXT: andi a5, a6, 63
240-
; CHECK-NEXT: bgeu a5, a4, .LBB9_8
241-
; CHECK-NEXT: .LBB9_6:
242-
; CHECK-NEXT: sll a4, a0, a6
243-
; CHECK-NEXT: neg a7, a5
244-
; CHECK-NEXT: srl a0, a0, a7
245-
; CHECK-NEXT: sll a6, a1, a6
246-
; CHECK-NEXT: or a0, a0, a6
247-
; CHECK-NEXT: bnez a5, .LBB9_9
248-
; CHECK-NEXT: j .LBB9_10
249-
; CHECK-NEXT: .LBB9_7:
250-
; CHECK-NEXT: srl a2, a1, a2
251-
; CHECK-NEXT: andi a5, a6, 63
252-
; CHECK-NEXT: bltu a5, a4, .LBB9_6
253-
; CHECK-NEXT: .LBB9_8:
254-
; CHECK-NEXT: li a4, 0
255-
; CHECK-NEXT: sll a0, a0, a5
256-
; CHECK-NEXT: beqz a5, .LBB9_10
257-
; CHECK-NEXT: .LBB9_9:
258-
; CHECK-NEXT: mv a1, a0
259-
; CHECK-NEXT: .LBB9_10:
260-
; CHECK-NEXT: or a0, a3, a4
261-
; CHECK-NEXT: or a1, a2, a1
262-
; CHECK-NEXT: ret
304+
; RV32I-LABEL: ror_i64:
305+
; RV32I: # %bb.0:
306+
; RV32I-NEXT: andi a5, a2, 63
307+
; RV32I-NEXT: li a4, 32
308+
; RV32I-NEXT: bltu a5, a4, .LBB11_2
309+
; RV32I-NEXT: # %bb.1:
310+
; RV32I-NEXT: srl a6, a1, a5
311+
; RV32I-NEXT: mv a3, a0
312+
; RV32I-NEXT: bnez a5, .LBB11_3
313+
; RV32I-NEXT: j .LBB11_4
314+
; RV32I-NEXT: .LBB11_2:
315+
; RV32I-NEXT: srl a3, a0, a2
316+
; RV32I-NEXT: neg a6, a5
317+
; RV32I-NEXT: sll a6, a1, a6
318+
; RV32I-NEXT: or a6, a3, a6
319+
; RV32I-NEXT: mv a3, a0
320+
; RV32I-NEXT: beqz a5, .LBB11_4
321+
; RV32I-NEXT: .LBB11_3:
322+
; RV32I-NEXT: mv a3, a6
323+
; RV32I-NEXT: .LBB11_4:
324+
; RV32I-NEXT: neg a6, a2
325+
; RV32I-NEXT: bltu a5, a4, .LBB11_7
326+
; RV32I-NEXT: # %bb.5:
327+
; RV32I-NEXT: li a2, 0
328+
; RV32I-NEXT: andi a5, a6, 63
329+
; RV32I-NEXT: bgeu a5, a4, .LBB11_8
330+
; RV32I-NEXT: .LBB11_6:
331+
; RV32I-NEXT: sll a4, a0, a6
332+
; RV32I-NEXT: neg a7, a5
333+
; RV32I-NEXT: srl a0, a0, a7
334+
; RV32I-NEXT: sll a6, a1, a6
335+
; RV32I-NEXT: or a0, a0, a6
336+
; RV32I-NEXT: bnez a5, .LBB11_9
337+
; RV32I-NEXT: j .LBB11_10
338+
; RV32I-NEXT: .LBB11_7:
339+
; RV32I-NEXT: srl a2, a1, a2
340+
; RV32I-NEXT: andi a5, a6, 63
341+
; RV32I-NEXT: bltu a5, a4, .LBB11_6
342+
; RV32I-NEXT: .LBB11_8:
343+
; RV32I-NEXT: li a4, 0
344+
; RV32I-NEXT: sll a0, a0, a5
345+
; RV32I-NEXT: beqz a5, .LBB11_10
346+
; RV32I-NEXT: .LBB11_9:
347+
; RV32I-NEXT: mv a1, a0
348+
; RV32I-NEXT: .LBB11_10:
349+
; RV32I-NEXT: or a0, a3, a4
350+
; RV32I-NEXT: or a1, a2, a1
351+
; RV32I-NEXT: ret
352+
;
353+
; RV32ZBB-ZBKB-LABEL: ror_i64:
354+
; RV32ZBB-ZBKB: # %bb.0:
355+
; RV32ZBB-ZBKB-NEXT: andi a4, a2, 63
356+
; RV32ZBB-ZBKB-NEXT: li a5, 32
357+
; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_2
358+
; RV32ZBB-ZBKB-NEXT: # %bb.1:
359+
; RV32ZBB-ZBKB-NEXT: srl a6, a1, a4
360+
; RV32ZBB-ZBKB-NEXT: mv a3, a0
361+
; RV32ZBB-ZBKB-NEXT: bnez a4, .LBB11_3
362+
; RV32ZBB-ZBKB-NEXT: j .LBB11_4
363+
; RV32ZBB-ZBKB-NEXT: .LBB11_2:
364+
; RV32ZBB-ZBKB-NEXT: srl a3, a0, a2
365+
; RV32ZBB-ZBKB-NEXT: neg a6, a4
366+
; RV32ZBB-ZBKB-NEXT: sll a6, a1, a6
367+
; RV32ZBB-ZBKB-NEXT: or a6, a3, a6
368+
; RV32ZBB-ZBKB-NEXT: mv a3, a0
369+
; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB11_4
370+
; RV32ZBB-ZBKB-NEXT: .LBB11_3:
371+
; RV32ZBB-ZBKB-NEXT: mv a3, a6
372+
; RV32ZBB-ZBKB-NEXT: .LBB11_4:
373+
; RV32ZBB-ZBKB-NEXT: li a6, 63
374+
; RV32ZBB-ZBKB-NEXT: bltu a4, a5, .LBB11_7
375+
; RV32ZBB-ZBKB-NEXT: # %bb.5:
376+
; RV32ZBB-ZBKB-NEXT: li a4, 0
377+
; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
378+
; RV32ZBB-ZBKB-NEXT: bgeu a6, a5, .LBB11_8
379+
; RV32ZBB-ZBKB-NEXT: .LBB11_6:
380+
; RV32ZBB-ZBKB-NEXT: neg a5, a2
381+
; RV32ZBB-ZBKB-NEXT: neg a7, a6
382+
; RV32ZBB-ZBKB-NEXT: sll a2, a0, a5
383+
; RV32ZBB-ZBKB-NEXT: srl a0, a0, a7
384+
; RV32ZBB-ZBKB-NEXT: sll a5, a1, a5
385+
; RV32ZBB-ZBKB-NEXT: or a0, a0, a5
386+
; RV32ZBB-ZBKB-NEXT: bnez a6, .LBB11_9
387+
; RV32ZBB-ZBKB-NEXT: j .LBB11_10
388+
; RV32ZBB-ZBKB-NEXT: .LBB11_7:
389+
; RV32ZBB-ZBKB-NEXT: srl a4, a1, a2
390+
; RV32ZBB-ZBKB-NEXT: andn a6, a6, a2
391+
; RV32ZBB-ZBKB-NEXT: bltu a6, a5, .LBB11_6
392+
; RV32ZBB-ZBKB-NEXT: .LBB11_8:
393+
; RV32ZBB-ZBKB-NEXT: li a2, 0
394+
; RV32ZBB-ZBKB-NEXT: sll a0, a0, a6
395+
; RV32ZBB-ZBKB-NEXT: beqz a6, .LBB11_10
396+
; RV32ZBB-ZBKB-NEXT: .LBB11_9:
397+
; RV32ZBB-ZBKB-NEXT: mv a1, a0
398+
; RV32ZBB-ZBKB-NEXT: .LBB11_10:
399+
; RV32ZBB-ZBKB-NEXT: or a0, a3, a2
400+
; RV32ZBB-ZBKB-NEXT: or a1, a4, a1
401+
; RV32ZBB-ZBKB-NEXT: ret
263402
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
264403
ret i64 %or
265404
}

0 commit comments

Comments
 (0)