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 a3, a2, 26
142 ; CHECK-NEXT: srli a3, a3, 31
143 ; CHECK-NEXT: mv a4, a1
144 ; CHECK-NEXT: bnez a3, .LBB7_2
145 ; CHECK-NEXT: # %bb.1:
146 ; CHECK-NEXT: mv a4, a0
147 ; CHECK-NEXT: .LBB7_2:
148 ; CHECK-NEXT: sll a5, a4, a2
149 ; CHECK-NEXT: bnez a3, .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 a6, a2
155 ; CHECK-NEXT: srl a3, a1, a6
156 ; CHECK-NEXT: or a3, a5, a3
157 ; CHECK-NEXT: sll a0, a0, a2
158 ; CHECK-NEXT: srli a4, a4, 1
159 ; CHECK-NEXT: srl a1, a4, a6
160 ; CHECK-NEXT: or a1, a0, a1
161 ; CHECK-NEXT: mv a0, a3
163 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
167 declare i32 @llvm.fshr.i32(i32, i32, i32)
169 define i32 @ror_i32(i32 %a, i32 %b) nounwind {
170 ; RV32I-LABEL: ror_i32:
172 ; RV32I-NEXT: srl a2, a0, a1
173 ; RV32I-NEXT: neg a1, a1
174 ; RV32I-NEXT: sll a0, a0, a1
175 ; RV32I-NEXT: or a0, a2, a0
178 ; RV32ZBB-ZBKB-LABEL: ror_i32:
179 ; RV32ZBB-ZBKB: # %bb.0:
180 ; RV32ZBB-ZBKB-NEXT: ror a0, a0, a1
181 ; RV32ZBB-ZBKB-NEXT: ret
182 %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
186 ; This test is presented here in case future expansions of the Bitmanip
187 ; extensions introduce instructions suitable for this pattern.
189 declare i64 @llvm.fshr.i64(i64, i64, i64)
191 define i64 @ror_i64(i64 %a, i64 %b) nounwind {
192 ; CHECK-LABEL: ror_i64:
194 ; CHECK-NEXT: andi a4, a2, 32
195 ; CHECK-NEXT: mv a3, a0
196 ; CHECK-NEXT: beqz a4, .LBB9_2
197 ; CHECK-NEXT: # %bb.1:
198 ; CHECK-NEXT: mv a3, a1
199 ; CHECK-NEXT: .LBB9_2:
200 ; CHECK-NEXT: srl a5, a3, a2
201 ; CHECK-NEXT: beqz a4, .LBB9_4
202 ; CHECK-NEXT: # %bb.3:
203 ; CHECK-NEXT: mv a1, a0
204 ; CHECK-NEXT: .LBB9_4:
205 ; CHECK-NEXT: slli a0, a1, 1
206 ; CHECK-NEXT: not a4, a2
207 ; CHECK-NEXT: sll a0, a0, a4
208 ; CHECK-NEXT: or a0, a0, a5
209 ; CHECK-NEXT: srl a1, a1, a2
210 ; CHECK-NEXT: slli a3, a3, 1
211 ; CHECK-NEXT: sll a2, a3, a4
212 ; CHECK-NEXT: or a1, a2, a1
214 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
218 define i32 @rori_i32_fshl(i32 %a) nounwind {
219 ; RV32I-LABEL: rori_i32_fshl:
221 ; RV32I-NEXT: srli a1, a0, 1
222 ; RV32I-NEXT: slli a0, a0, 31
223 ; RV32I-NEXT: or a0, a0, a1
226 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshl:
227 ; RV32ZBB-ZBKB: # %bb.0:
228 ; RV32ZBB-ZBKB-NEXT: rori a0, a0, 1
229 ; RV32ZBB-ZBKB-NEXT: ret
230 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
234 define i32 @rori_i32_fshr(i32 %a) nounwind {
235 ; RV32I-LABEL: rori_i32_fshr:
237 ; RV32I-NEXT: slli a1, a0, 1
238 ; RV32I-NEXT: srli a0, a0, 31
239 ; RV32I-NEXT: or a0, a0, a1
242 ; RV32ZBB-ZBKB-LABEL: rori_i32_fshr:
243 ; RV32ZBB-ZBKB: # %bb.0:
244 ; RV32ZBB-ZBKB-NEXT: rori a0, a0, 31
245 ; RV32ZBB-ZBKB-NEXT: ret
246 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
250 define i64 @rori_i64(i64 %a) nounwind {
251 ; CHECK-LABEL: rori_i64:
253 ; CHECK-NEXT: srli a2, a0, 1
254 ; CHECK-NEXT: slli a3, a1, 31
255 ; CHECK-NEXT: or a2, a3, a2
256 ; CHECK-NEXT: srli a1, a1, 1
257 ; CHECK-NEXT: slli a0, a0, 31
258 ; CHECK-NEXT: or a1, a0, a1
259 ; CHECK-NEXT: mv a0, a2
261 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
265 define i64 @rori_i64_fshr(i64 %a) nounwind {
266 ; CHECK-LABEL: rori_i64_fshr:
268 ; CHECK-NEXT: srli a2, a1, 31
269 ; CHECK-NEXT: slli a3, a0, 1
270 ; CHECK-NEXT: or a2, a3, a2
271 ; CHECK-NEXT: srli a0, a0, 31
272 ; CHECK-NEXT: slli a1, a1, 1
273 ; CHECK-NEXT: or a1, a1, a0
274 ; CHECK-NEXT: mv a0, a2
276 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
280 define i32 @not_shl_one_i32(i32 %x) {
281 ; RV32I-LABEL: not_shl_one_i32:
283 ; RV32I-NEXT: li a1, 1
284 ; RV32I-NEXT: sll a0, a1, a0
285 ; RV32I-NEXT: not a0, a0
288 ; RV32ZBB-ZBKB-LABEL: not_shl_one_i32:
289 ; RV32ZBB-ZBKB: # %bb.0:
290 ; RV32ZBB-ZBKB-NEXT: li a1, -2
291 ; RV32ZBB-ZBKB-NEXT: rol a0, a1, a0
292 ; RV32ZBB-ZBKB-NEXT: ret
298 define i64 @not_shl_one_i64(i64 %x) {
299 ; CHECK-LABEL: not_shl_one_i64:
301 ; CHECK-NEXT: addi a1, a0, -32
302 ; CHECK-NEXT: slti a1, a1, 0
303 ; CHECK-NEXT: neg a2, a1
304 ; CHECK-NEXT: li a3, 1
305 ; CHECK-NEXT: sll a0, a3, a0
306 ; CHECK-NEXT: and a2, a2, a0
307 ; CHECK-NEXT: addi a1, a1, -1
308 ; CHECK-NEXT: and a1, a1, a0
309 ; CHECK-NEXT: not a0, a2
310 ; CHECK-NEXT: not a1, a1
317 define i8 @srli_i8(i8 %a) nounwind {
318 ; CHECK-LABEL: srli_i8:
320 ; CHECK-NEXT: slli a0, a0, 24
321 ; CHECK-NEXT: srli a0, a0, 30
327 ; We could use sext.b+srai, but slli+srai offers more opportunities for
328 ; comppressed instructions.
329 define i8 @srai_i8(i8 %a) nounwind {
330 ; CHECK-LABEL: srai_i8:
332 ; CHECK-NEXT: slli a0, a0, 24
333 ; CHECK-NEXT: srai a0, a0, 29
339 ; We could use zext.h+srli, but slli+srli offers more opportunities for
340 ; comppressed instructions.
341 define i16 @srli_i16(i16 %a) nounwind {
342 ; CHECK-LABEL: srli_i16:
344 ; CHECK-NEXT: slli a0, a0, 16
345 ; CHECK-NEXT: srli a0, a0, 22
351 ; We could use sext.h+srai, but slli+srai offers more opportunities for
352 ; comppressed instructions.
353 define i16 @srai_i16(i16 %a) nounwind {
354 ; CHECK-LABEL: srai_i16:
356 ; CHECK-NEXT: slli a0, a0, 16
357 ; CHECK-NEXT: srai a0, a0, 25
363 define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
364 ; RV32I-LABEL: andn_seqz_i32:
366 ; RV32I-NEXT: and a0, a0, a1
367 ; RV32I-NEXT: xor a0, a0, a1
368 ; RV32I-NEXT: seqz a0, a0
371 ; RV32ZBB-ZBKB-LABEL: andn_seqz_i32:
372 ; RV32ZBB-ZBKB: # %bb.0:
373 ; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0
374 ; RV32ZBB-ZBKB-NEXT: seqz a0, a0
375 ; RV32ZBB-ZBKB-NEXT: ret
376 %and = and i32 %a, %b
377 %cmpeq = icmp eq i32 %and, %b
381 define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
382 ; RV32I-LABEL: andn_seqz_i64:
384 ; RV32I-NEXT: not a0, a0
385 ; RV32I-NEXT: not a1, a1
386 ; RV32I-NEXT: and a1, a1, a3
387 ; RV32I-NEXT: and a0, a0, a2
388 ; RV32I-NEXT: or a0, a0, a1
389 ; RV32I-NEXT: seqz a0, a0
392 ; RV32ZBB-ZBKB-LABEL: andn_seqz_i64:
393 ; RV32ZBB-ZBKB: # %bb.0:
394 ; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1
395 ; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0
396 ; RV32ZBB-ZBKB-NEXT: or a0, a0, a1
397 ; RV32ZBB-ZBKB-NEXT: seqz a0, a0
398 ; RV32ZBB-ZBKB-NEXT: ret
399 %and = and i64 %a, %b
400 %cmpeq = icmp eq i64 %and, %b
404 define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
405 ; RV32I-LABEL: andn_snez_i32:
407 ; RV32I-NEXT: and a0, a0, a1
408 ; RV32I-NEXT: xor a0, a0, a1
409 ; RV32I-NEXT: snez a0, a0
412 ; RV32ZBB-ZBKB-LABEL: andn_snez_i32:
413 ; RV32ZBB-ZBKB: # %bb.0:
414 ; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0
415 ; RV32ZBB-ZBKB-NEXT: snez a0, a0
416 ; RV32ZBB-ZBKB-NEXT: ret
417 %and = and i32 %a, %b
418 %cmpeq = icmp ne i32 %and, %b
422 define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
423 ; RV32I-LABEL: andn_snez_i64:
425 ; RV32I-NEXT: not a0, a0
426 ; RV32I-NEXT: not a1, a1
427 ; RV32I-NEXT: and a1, a1, a3
428 ; RV32I-NEXT: and a0, a0, a2
429 ; RV32I-NEXT: or a0, a0, a1
430 ; RV32I-NEXT: snez a0, a0
433 ; RV32ZBB-ZBKB-LABEL: andn_snez_i64:
434 ; RV32ZBB-ZBKB: # %bb.0:
435 ; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1
436 ; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0
437 ; RV32ZBB-ZBKB-NEXT: or a0, a0, a1
438 ; RV32ZBB-ZBKB-NEXT: snez a0, a0
439 ; RV32ZBB-ZBKB-NEXT: ret
440 %and = and i64 %a, %b
441 %cmpeq = icmp ne i64 %and, %b