1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I
4 ; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB
6 ; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB
9 define i32 @andn_i32(i32 %a, i32 %b) nounwind {
10 ; RV32I-LABEL: andn_i32:
12 ; RV32I-NEXT: not a1, a1
13 ; RV32I-NEXT: and a0, a1, a0
16 ; RV32ZBB-ZBKB-LABEL: andn_i32:
17 ; RV32ZBB-ZBKB: # %bb.0:
18 ; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1
19 ; RV32ZBB-ZBKB-NEXT: ret
21 %and = and i32 %neg, %a
25 define i64 @andn_i64(i64 %a, i64 %b) nounwind {
26 ; RV32I-LABEL: andn_i64:
28 ; RV32I-NEXT: not a3, a3
29 ; RV32I-NEXT: not a2, a2
30 ; RV32I-NEXT: and a0, a2, a0
31 ; RV32I-NEXT: and a1, a3, a1
34 ; RV32ZBB-ZBKB-LABEL: andn_i64:
35 ; RV32ZBB-ZBKB: # %bb.0:
36 ; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2
37 ; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3
38 ; RV32ZBB-ZBKB-NEXT: ret
40 %and = and i64 %neg, %a
44 define i32 @orn_i32(i32 %a, i32 %b) nounwind {
45 ; RV32I-LABEL: orn_i32:
47 ; RV32I-NEXT: not a1, a1
48 ; RV32I-NEXT: or a0, a1, a0
51 ; RV32ZBB-ZBKB-LABEL: orn_i32:
52 ; RV32ZBB-ZBKB: # %bb.0:
53 ; RV32ZBB-ZBKB-NEXT: orn a0, a0, a1
54 ; RV32ZBB-ZBKB-NEXT: ret
60 define i64 @orn_i64(i64 %a, i64 %b) nounwind {
61 ; RV32I-LABEL: orn_i64:
63 ; RV32I-NEXT: not a3, a3
64 ; RV32I-NEXT: not a2, a2
65 ; RV32I-NEXT: or a0, a2, a0
66 ; RV32I-NEXT: or a1, a3, a1
69 ; RV32ZBB-ZBKB-LABEL: orn_i64:
70 ; RV32ZBB-ZBKB: # %bb.0:
71 ; RV32ZBB-ZBKB-NEXT: orn a0, a0, a2
72 ; RV32ZBB-ZBKB-NEXT: orn a1, a1, a3
73 ; RV32ZBB-ZBKB-NEXT: ret
79 define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
80 ; RV32I-LABEL: xnor_i32:
82 ; RV32I-NEXT: xor a0, a0, a1
83 ; RV32I-NEXT: not a0, a0
86 ; RV32ZBB-ZBKB-LABEL: xnor_i32:
87 ; RV32ZBB-ZBKB: # %bb.0:
88 ; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a1
89 ; RV32ZBB-ZBKB-NEXT: ret
91 %xor = xor i32 %neg, %b
95 define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
96 ; RV32I-LABEL: xnor_i64:
98 ; RV32I-NEXT: xor a1, a1, a3
99 ; RV32I-NEXT: xor a0, a0, a2
100 ; RV32I-NEXT: not a0, a0
101 ; RV32I-NEXT: not a1, a1
104 ; RV32ZBB-ZBKB-LABEL: xnor_i64:
105 ; RV32ZBB-ZBKB: # %bb.0:
106 ; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a2
107 ; RV32ZBB-ZBKB-NEXT: xnor a1, a1, a3
108 ; RV32ZBB-ZBKB-NEXT: ret
109 %neg = xor i64 %a, -1
110 %xor = xor i64 %neg, %b
114 declare i32 @llvm.fshl.i32(i32, i32, i32)
116 define i32 @rol_i32(i32 %a, i32 %b) nounwind {
117 ; RV32I-LABEL: rol_i32:
119 ; RV32I-NEXT: sll a2, a0, a1
120 ; RV32I-NEXT: neg a1, a1
121 ; RV32I-NEXT: srl a0, a0, a1
122 ; RV32I-NEXT: or a0, a2, a0
125 ; RV32ZBB-ZBKB-LABEL: rol_i32:
126 ; RV32ZBB-ZBKB: # %bb.0:
127 ; RV32ZBB-ZBKB-NEXT: rol a0, a0, a1
128 ; RV32ZBB-ZBKB-NEXT: ret
129 %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
133 ; This test is presented here in case future expansions of the Bitmanip
134 ; extensions introduce instructions suitable for this pattern.
136 declare i64 @llvm.fshl.i64(i64, i64, i64)
138 define i64 @rol_i64(i64 %a, i64 %b) nounwind {
139 ; CHECK-LABEL: rol_i64:
141 ; CHECK-NEXT: slli a5, a2, 26
142 ; CHECK-NEXT: srli a5, a5, 31
143 ; CHECK-NEXT: mv a3, a1
144 ; CHECK-NEXT: bnez a5, .LBB7_2
145 ; CHECK-NEXT: # %bb.1:
146 ; CHECK-NEXT: mv a3, a0
147 ; CHECK-NEXT: .LBB7_2:
148 ; CHECK-NEXT: sll a4, a3, a2
149 ; CHECK-NEXT: bnez a5, .LBB7_4
150 ; CHECK-NEXT: # %bb.3:
151 ; CHECK-NEXT: mv a0, a1
152 ; CHECK-NEXT: .LBB7_4:
153 ; CHECK-NEXT: srli a1, a0, 1
154 ; CHECK-NEXT: not a5, a2
155 ; CHECK-NEXT: sll a2, a0, a2
156 ; CHECK-NEXT: srli a3, a3, 1
157 ; CHECK-NEXT: srl a0, a1, a5
158 ; CHECK-NEXT: srl a1, a3, a5
159 ; CHECK-NEXT: or a0, a4, a0
160 ; CHECK-NEXT: or a1, a2, a1
162 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
166 declare i32 @llvm.fshr.i32(i32, i32, i32)
168 define i32 @ror_i32(i32 %a, i32 %b) nounwind {
169 ; RV32I-LABEL: ror_i32:
171 ; RV32I-NEXT: srl a2, a0, a1
172 ; RV32I-NEXT: neg a1, a1
173 ; RV32I-NEXT: sll a0, a0, a1
174 ; RV32I-NEXT: or a0, a2, a0
177 ; RV32ZBB-ZBKB-LABEL: ror_i32:
178 ; RV32ZBB-ZBKB: # %bb.0:
179 ; RV32ZBB-ZBKB-NEXT: ror a0, a0, a1
180 ; RV32ZBB-ZBKB-NEXT: ret
181 %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
185 ; This test is presented here in case future expansions of the Bitmanip
186 ; extensions introduce instructions suitable for this pattern.
188 declare i64 @llvm.fshr.i64(i64, i64, i64)
190 define i64 @ror_i64(i64 %a, i64 %b) nounwind {
191 ; CHECK-LABEL: ror_i64:
193 ; CHECK-NEXT: andi a5, a2, 32
194 ; CHECK-NEXT: mv a3, a0
195 ; CHECK-NEXT: beqz a5, .LBB9_2
196 ; CHECK-NEXT: # %bb.1:
197 ; CHECK-NEXT: mv a3, a1
198 ; CHECK-NEXT: .LBB9_2:
199 ; CHECK-NEXT: srl a4, a3, a2
200 ; CHECK-NEXT: beqz a5, .LBB9_4
201 ; CHECK-NEXT: # %bb.3:
202 ; CHECK-NEXT: mv a1, a0
203 ; CHECK-NEXT: .LBB9_4:
204 ; CHECK-NEXT: slli a0, a1, 1
205 ; CHECK-NEXT: not a5, a2
206 ; CHECK-NEXT: srl a1, a1, a2
207 ; CHECK-NEXT: slli a3, a3, 1
208 ; CHECK-NEXT: sll a0, a0, a5
209 ; CHECK-NEXT: sll a2, a3, a5
210 ; CHECK-NEXT: or a0, a0, a4
211 ; CHECK-NEXT: or a1, a2, a1
213 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
217 define i32 @rori_i32_fshl(i32 %a) nounwind {
218 ; RV32I-LABEL: rori_i32_fshl:
220 ; RV32I-NEXT: srli a1, a0, 1
221 ; RV32I-NEXT: slli a0, a0, 31
222 ; RV32I-NEXT: or a0, a0, a1
225 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshl:
226 ; RV32ZBB-ZBKB: # %bb.0:
227 ; RV32ZBB-ZBKB-NEXT: rori a0, a0, 1
228 ; RV32ZBB-ZBKB-NEXT: ret
229 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
233 define i32 @rori_i32_fshr(i32 %a) nounwind {
234 ; RV32I-LABEL: rori_i32_fshr:
236 ; RV32I-NEXT: slli a1, a0, 1
237 ; RV32I-NEXT: srli a0, a0, 31
238 ; RV32I-NEXT: or a0, a0, a1
241 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshr:
242 ; RV32ZBB-ZBKB: # %bb.0:
243 ; RV32ZBB-ZBKB-NEXT: rori a0, a0, 31
244 ; RV32ZBB-ZBKB-NEXT: ret
245 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
249 define i64 @rori_i64(i64 %a) nounwind {
250 ; CHECK-LABEL: rori_i64:
252 ; CHECK-NEXT: srli a2, a0, 1
253 ; CHECK-NEXT: slli a3, a1, 31
254 ; CHECK-NEXT: srli a1, a1, 1
255 ; CHECK-NEXT: slli a4, a0, 31
256 ; CHECK-NEXT: or a0, a3, a2
257 ; CHECK-NEXT: or a1, a4, a1
259 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
263 define i64 @rori_i64_fshr(i64 %a) nounwind {
264 ; CHECK-LABEL: rori_i64_fshr:
266 ; CHECK-NEXT: srli a2, a1, 31
267 ; CHECK-NEXT: slli a3, a0, 1
268 ; CHECK-NEXT: srli a4, a0, 31
269 ; CHECK-NEXT: slli a1, a1, 1
270 ; CHECK-NEXT: or a0, a3, a2
271 ; CHECK-NEXT: or a1, a1, a4
273 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
277 define i32 @not_shl_one_i32(i32 %x) {
278 ; RV32I-LABEL: not_shl_one_i32:
280 ; RV32I-NEXT: li a1, 1
281 ; RV32I-NEXT: sll a0, a1, a0
282 ; RV32I-NEXT: not a0, a0
285 ; RV32ZBB-ZBKB-LABEL: not_shl_one_i32:
286 ; RV32ZBB-ZBKB: # %bb.0:
287 ; RV32ZBB-ZBKB-NEXT: li a1, -2
288 ; RV32ZBB-ZBKB-NEXT: rol a0, a1, a0
289 ; RV32ZBB-ZBKB-NEXT: ret
295 define i64 @not_shl_one_i64(i64 %x) {
296 ; CHECK-LABEL: not_shl_one_i64:
298 ; CHECK-NEXT: addi a1, a0, -32
299 ; CHECK-NEXT: li a2, 1
300 ; CHECK-NEXT: slti a1, a1, 0
301 ; CHECK-NEXT: sll a0, a2, a0
302 ; CHECK-NEXT: neg a2, a1
303 ; CHECK-NEXT: addi a1, a1, -1
304 ; CHECK-NEXT: and a2, a2, a0
305 ; CHECK-NEXT: and a1, a1, a0
306 ; CHECK-NEXT: not a0, a2
307 ; CHECK-NEXT: not a1, a1
314 define i8 @srli_i8(i8 %a) nounwind {
315 ; CHECK-LABEL: srli_i8:
317 ; CHECK-NEXT: slli a0, a0, 24
318 ; CHECK-NEXT: srli a0, a0, 30
324 ; We could use sext.b+srai, but slli+srai offers more opportunities for
325 ; comppressed instructions.
326 define i8 @srai_i8(i8 %a) nounwind {
327 ; CHECK-LABEL: srai_i8:
329 ; CHECK-NEXT: slli a0, a0, 24
330 ; CHECK-NEXT: srai a0, a0, 29
336 ; We could use zext.h+srli, but slli+srli offers more opportunities for
337 ; comppressed instructions.
338 define i16 @srli_i16(i16 %a) nounwind {
339 ; CHECK-LABEL: srli_i16:
341 ; CHECK-NEXT: slli a0, a0, 16
342 ; CHECK-NEXT: srli a0, a0, 22
348 ; We could use sext.h+srai, but slli+srai offers more opportunities for
349 ; comppressed instructions.
350 define i16 @srai_i16(i16 %a) nounwind {
351 ; CHECK-LABEL: srai_i16:
353 ; CHECK-NEXT: slli a0, a0, 16
354 ; CHECK-NEXT: srai a0, a0, 25
360 define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
361 ; RV32I-LABEL: andn_seqz_i32:
363 ; RV32I-NEXT: and a0, a0, a1
364 ; RV32I-NEXT: xor a0, a0, a1
365 ; RV32I-NEXT: seqz a0, a0
368 ; RV32ZBB-ZBKB-LABEL: andn_seqz_i32:
369 ; RV32ZBB-ZBKB: # %bb.0:
370 ; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0
371 ; RV32ZBB-ZBKB-NEXT: seqz a0, a0
372 ; RV32ZBB-ZBKB-NEXT: ret
373 %and = and i32 %a, %b
374 %cmpeq = icmp eq i32 %and, %b
378 define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
379 ; RV32I-LABEL: andn_seqz_i64:
381 ; RV32I-NEXT: not a0, a0
382 ; RV32I-NEXT: not a1, a1
383 ; RV32I-NEXT: and a1, a1, a3
384 ; RV32I-NEXT: and a0, a0, a2
385 ; RV32I-NEXT: or a0, a0, a1
386 ; RV32I-NEXT: seqz a0, a0
389 ; RV32ZBB-ZBKB-LABEL: andn_seqz_i64:
390 ; RV32ZBB-ZBKB: # %bb.0:
391 ; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1
392 ; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0
393 ; RV32ZBB-ZBKB-NEXT: or a0, a0, a1
394 ; RV32ZBB-ZBKB-NEXT: seqz a0, a0
395 ; RV32ZBB-ZBKB-NEXT: ret
396 %and = and i64 %a, %b
397 %cmpeq = icmp eq i64 %and, %b
401 define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
402 ; RV32I-LABEL: andn_snez_i32:
404 ; RV32I-NEXT: and a0, a0, a1
405 ; RV32I-NEXT: xor a0, a0, a1
406 ; RV32I-NEXT: snez a0, a0
409 ; RV32ZBB-ZBKB-LABEL: andn_snez_i32:
410 ; RV32ZBB-ZBKB: # %bb.0:
411 ; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0
412 ; RV32ZBB-ZBKB-NEXT: snez a0, a0
413 ; RV32ZBB-ZBKB-NEXT: ret
414 %and = and i32 %a, %b
415 %cmpeq = icmp ne i32 %and, %b
419 define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
420 ; RV32I-LABEL: andn_snez_i64:
422 ; RV32I-NEXT: not a0, a0
423 ; RV32I-NEXT: not a1, a1
424 ; RV32I-NEXT: and a1, a1, a3
425 ; RV32I-NEXT: and a0, a0, a2
426 ; RV32I-NEXT: or a0, a0, a1
427 ; RV32I-NEXT: snez a0, a0
430 ; RV32ZBB-ZBKB-LABEL: andn_snez_i64:
431 ; RV32ZBB-ZBKB: # %bb.0:
432 ; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1
433 ; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0
434 ; RV32ZBB-ZBKB-NEXT: or a0, a0, a1
435 ; RV32ZBB-ZBKB-NEXT: snez a0, a0
436 ; RV32ZBB-ZBKB-NEXT: ret
437 %and = and i64 %a, %b
438 %cmpeq = icmp ne i64 %and, %b