[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv32zbb-zbp-zbkb.ll
bloba6e504f700bc50f250b74f784cffa17b8009a239
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-ZBP-ZBKB
6 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBP-ZBKB
8 ; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBP-ZBKB
11 define i32 @andn_i32(i32 %a, i32 %b) nounwind {
12 ; RV32I-LABEL: andn_i32:
13 ; RV32I:       # %bb.0:
14 ; RV32I-NEXT:    not a1, a1
15 ; RV32I-NEXT:    and a0, a1, a0
16 ; RV32I-NEXT:    ret
18 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_i32:
19 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
20 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a0, a1
21 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
22   %neg = xor i32 %b, -1
23   %and = and i32 %neg, %a
24   ret i32 %and
27 define i64 @andn_i64(i64 %a, i64 %b) nounwind {
28 ; RV32I-LABEL: andn_i64:
29 ; RV32I:       # %bb.0:
30 ; RV32I-NEXT:    not a3, a3
31 ; RV32I-NEXT:    not a2, a2
32 ; RV32I-NEXT:    and a0, a2, a0
33 ; RV32I-NEXT:    and a1, a3, a1
34 ; RV32I-NEXT:    ret
36 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_i64:
37 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
38 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a0, a2
39 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a1, a1, a3
40 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
41   %neg = xor i64 %b, -1
42   %and = and i64 %neg, %a
43   ret i64 %and
46 define i32 @orn_i32(i32 %a, i32 %b) nounwind {
47 ; RV32I-LABEL: orn_i32:
48 ; RV32I:       # %bb.0:
49 ; RV32I-NEXT:    not a1, a1
50 ; RV32I-NEXT:    or a0, a1, a0
51 ; RV32I-NEXT:    ret
53 ; RV32ZBB-ZBP-ZBKB-LABEL: orn_i32:
54 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
55 ; RV32ZBB-ZBP-ZBKB-NEXT:    orn a0, a0, a1
56 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
57   %neg = xor i32 %b, -1
58   %or = or i32 %neg, %a
59   ret i32 %or
62 define i64 @orn_i64(i64 %a, i64 %b) nounwind {
63 ; RV32I-LABEL: orn_i64:
64 ; RV32I:       # %bb.0:
65 ; RV32I-NEXT:    not a3, a3
66 ; RV32I-NEXT:    not a2, a2
67 ; RV32I-NEXT:    or a0, a2, a0
68 ; RV32I-NEXT:    or a1, a3, a1
69 ; RV32I-NEXT:    ret
71 ; RV32ZBB-ZBP-ZBKB-LABEL: orn_i64:
72 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
73 ; RV32ZBB-ZBP-ZBKB-NEXT:    orn a0, a0, a2
74 ; RV32ZBB-ZBP-ZBKB-NEXT:    orn a1, a1, a3
75 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
76   %neg = xor i64 %b, -1
77   %or = or i64 %neg, %a
78   ret i64 %or
81 define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
82 ; RV32I-LABEL: xnor_i32:
83 ; RV32I:       # %bb.0:
84 ; RV32I-NEXT:    xor a0, a0, a1
85 ; RV32I-NEXT:    not a0, a0
86 ; RV32I-NEXT:    ret
88 ; RV32ZBB-ZBP-ZBKB-LABEL: xnor_i32:
89 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
90 ; RV32ZBB-ZBP-ZBKB-NEXT:    xnor a0, a0, a1
91 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
92   %neg = xor i32 %a, -1
93   %xor = xor i32 %neg, %b
94   ret i32 %xor
97 define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
98 ; RV32I-LABEL: xnor_i64:
99 ; RV32I:       # %bb.0:
100 ; RV32I-NEXT:    xor a1, a1, a3
101 ; RV32I-NEXT:    xor a0, a0, a2
102 ; RV32I-NEXT:    not a0, a0
103 ; RV32I-NEXT:    not a1, a1
104 ; RV32I-NEXT:    ret
106 ; RV32ZBB-ZBP-ZBKB-LABEL: xnor_i64:
107 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
108 ; RV32ZBB-ZBP-ZBKB-NEXT:    xnor a0, a0, a2
109 ; RV32ZBB-ZBP-ZBKB-NEXT:    xnor a1, a1, a3
110 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
111   %neg = xor i64 %a, -1
112   %xor = xor i64 %neg, %b
113   ret i64 %xor
116 declare i32 @llvm.fshl.i32(i32, i32, i32)
118 define i32 @rol_i32(i32 %a, i32 %b) nounwind {
119 ; RV32I-LABEL: rol_i32:
120 ; RV32I:       # %bb.0:
121 ; RV32I-NEXT:    sll a2, a0, a1
122 ; RV32I-NEXT:    neg a1, a1
123 ; RV32I-NEXT:    srl a0, a0, a1
124 ; RV32I-NEXT:    or a0, a2, a0
125 ; RV32I-NEXT:    ret
127 ; RV32ZBB-ZBP-ZBKB-LABEL: rol_i32:
128 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
129 ; RV32ZBB-ZBP-ZBKB-NEXT:    rol a0, a0, a1
130 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
131   %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
132   ret i32 %or
135 ; This test is presented here in case future expansions of the Bitmanip
136 ; extensions introduce instructions suitable for this pattern.
138 declare i64 @llvm.fshl.i64(i64, i64, i64)
140 define i64 @rol_i64(i64 %a, i64 %b) nounwind {
141 ; CHECK-LABEL: rol_i64:
142 ; CHECK:       # %bb.0:
143 ; CHECK-NEXT:    slli a3, a2, 26
144 ; CHECK-NEXT:    srli a5, a3, 31
145 ; CHECK-NEXT:    mv a4, a1
146 ; CHECK-NEXT:    bnez a5, .LBB7_2
147 ; CHECK-NEXT:  # %bb.1:
148 ; CHECK-NEXT:    mv a4, a0
149 ; CHECK-NEXT:  .LBB7_2:
150 ; CHECK-NEXT:    sll a3, a4, a2
151 ; CHECK-NEXT:    bnez a5, .LBB7_4
152 ; CHECK-NEXT:  # %bb.3:
153 ; CHECK-NEXT:    mv a0, a1
154 ; CHECK-NEXT:  .LBB7_4:
155 ; CHECK-NEXT:    srli a1, a0, 1
156 ; CHECK-NEXT:    not a5, a2
157 ; CHECK-NEXT:    srl a1, a1, a5
158 ; CHECK-NEXT:    or a3, a3, a1
159 ; CHECK-NEXT:    sll a0, a0, a2
160 ; CHECK-NEXT:    srli a1, a4, 1
161 ; CHECK-NEXT:    srl a1, a1, a5
162 ; CHECK-NEXT:    or a1, a0, a1
163 ; CHECK-NEXT:    mv a0, a3
164 ; CHECK-NEXT:    ret
165   %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
166   ret i64 %or
169 declare i32 @llvm.fshr.i32(i32, i32, i32)
171 define i32 @ror_i32(i32 %a, i32 %b) nounwind {
172 ; RV32I-LABEL: ror_i32:
173 ; RV32I:       # %bb.0:
174 ; RV32I-NEXT:    srl a2, a0, a1
175 ; RV32I-NEXT:    neg a1, a1
176 ; RV32I-NEXT:    sll a0, a0, a1
177 ; RV32I-NEXT:    or a0, a2, a0
178 ; RV32I-NEXT:    ret
180 ; RV32ZBB-ZBP-ZBKB-LABEL: ror_i32:
181 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
182 ; RV32ZBB-ZBP-ZBKB-NEXT:    ror a0, a0, a1
183 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
184   %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
185   ret i32 %or
188 ; This test is presented here in case future expansions of the Bitmanip
189 ; extensions introduce instructions suitable for this pattern.
191 declare i64 @llvm.fshr.i64(i64, i64, i64)
193 define i64 @ror_i64(i64 %a, i64 %b) nounwind {
194 ; CHECK-LABEL: ror_i64:
195 ; CHECK:       # %bb.0:
196 ; CHECK-NEXT:    andi a5, a2, 32
197 ; CHECK-NEXT:    mv a3, a0
198 ; CHECK-NEXT:    beqz a5, .LBB9_2
199 ; CHECK-NEXT:  # %bb.1:
200 ; CHECK-NEXT:    mv a3, a1
201 ; CHECK-NEXT:  .LBB9_2:
202 ; CHECK-NEXT:    srl a4, a3, a2
203 ; CHECK-NEXT:    beqz a5, .LBB9_4
204 ; CHECK-NEXT:  # %bb.3:
205 ; CHECK-NEXT:    mv a1, a0
206 ; CHECK-NEXT:  .LBB9_4:
207 ; CHECK-NEXT:    slli a0, a1, 1
208 ; CHECK-NEXT:    not a5, a2
209 ; CHECK-NEXT:    sll a0, a0, a5
210 ; CHECK-NEXT:    or a0, a0, a4
211 ; CHECK-NEXT:    srl a1, a1, a2
212 ; CHECK-NEXT:    slli a2, a3, 1
213 ; CHECK-NEXT:    sll a2, a2, a5
214 ; CHECK-NEXT:    or a1, a2, a1
215 ; CHECK-NEXT:    ret
216   %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
217   ret i64 %or
220 define i32 @rori_i32_fshl(i32 %a) nounwind {
221 ; RV32I-LABEL: rori_i32_fshl:
222 ; RV32I:       # %bb.0:
223 ; RV32I-NEXT:    srli a1, a0, 1
224 ; RV32I-NEXT:    slli a0, a0, 31
225 ; RV32I-NEXT:    or a0, a0, a1
226 ; RV32I-NEXT:    ret
228 ; RV32ZBB-ZBP-ZBKB-LABEL: rori_i32_fshl:
229 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
230 ; RV32ZBB-ZBP-ZBKB-NEXT:    rori a0, a0, 1
231 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
232   %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
233   ret i32 %1
236 define i32 @rori_i32_fshr(i32 %a) nounwind {
237 ; RV32I-LABEL: rori_i32_fshr:
238 ; RV32I:       # %bb.0:
239 ; RV32I-NEXT:    slli a1, a0, 1
240 ; RV32I-NEXT:    srli a0, a0, 31
241 ; RV32I-NEXT:    or a0, a0, a1
242 ; RV32I-NEXT:    ret
244 ; RV32ZBB-ZBP-ZBKB-LABEL: rori_i32_fshr:
245 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
246 ; RV32ZBB-ZBP-ZBKB-NEXT:    rori a0, a0, 31
247 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
248   %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
249   ret i32 %1
252 define i64 @rori_i64(i64 %a) nounwind {
253 ; CHECK-LABEL: rori_i64:
254 ; CHECK:       # %bb.0:
255 ; CHECK-NEXT:    srli a2, a0, 1
256 ; CHECK-NEXT:    slli a3, a1, 31
257 ; CHECK-NEXT:    or a2, a3, a2
258 ; CHECK-NEXT:    srli a1, a1, 1
259 ; CHECK-NEXT:    slli a0, a0, 31
260 ; CHECK-NEXT:    or a1, a0, a1
261 ; CHECK-NEXT:    mv a0, a2
262 ; CHECK-NEXT:    ret
263   %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
264   ret i64 %1
267 define i64 @rori_i64_fshr(i64 %a) nounwind {
268 ; CHECK-LABEL: rori_i64_fshr:
269 ; CHECK:       # %bb.0:
270 ; CHECK-NEXT:    srli a2, a1, 31
271 ; CHECK-NEXT:    slli a3, a0, 1
272 ; CHECK-NEXT:    or a2, a3, a2
273 ; CHECK-NEXT:    srli a0, a0, 31
274 ; CHECK-NEXT:    slli a1, a1, 1
275 ; CHECK-NEXT:    or a1, a1, a0
276 ; CHECK-NEXT:    mv a0, a2
277 ; CHECK-NEXT:    ret
278   %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
279   ret i64 %1
282 define i32 @not_shl_one_i32(i32 %x) {
283 ; RV32I-LABEL: not_shl_one_i32:
284 ; RV32I:       # %bb.0:
285 ; RV32I-NEXT:    li a1, 1
286 ; RV32I-NEXT:    sll a0, a1, a0
287 ; RV32I-NEXT:    not a0, a0
288 ; RV32I-NEXT:    ret
290 ; RV32ZBB-ZBP-ZBKB-LABEL: not_shl_one_i32:
291 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
292 ; RV32ZBB-ZBP-ZBKB-NEXT:    li a1, -2
293 ; RV32ZBB-ZBP-ZBKB-NEXT:    rol a0, a1, a0
294 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
295   %1 = shl i32 1, %x
296   %2 = xor i32 %1, -1
297   ret i32 %2
300 define i64 @not_shl_one_i64(i64 %x) {
301 ; RV32I-LABEL: not_shl_one_i64:
302 ; RV32I:       # %bb.0:
303 ; RV32I-NEXT:    addi a3, a0, -32
304 ; RV32I-NEXT:    li a2, 1
305 ; RV32I-NEXT:    li a1, -1
306 ; RV32I-NEXT:    bltz a3, .LBB15_2
307 ; RV32I-NEXT:  # %bb.1:
308 ; RV32I-NEXT:    sll a0, a2, a3
309 ; RV32I-NEXT:    not a1, a0
310 ; RV32I-NEXT:    li a0, -1
311 ; RV32I-NEXT:    ret
312 ; RV32I-NEXT:  .LBB15_2:
313 ; RV32I-NEXT:    sll a0, a2, a0
314 ; RV32I-NEXT:    not a0, a0
315 ; RV32I-NEXT:    ret
317 ; RV32ZBB-ZBP-ZBKB-LABEL: not_shl_one_i64:
318 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
319 ; RV32ZBB-ZBP-ZBKB-NEXT:    addi a3, a0, -32
320 ; RV32ZBB-ZBP-ZBKB-NEXT:    li a2, -2
321 ; RV32ZBB-ZBP-ZBKB-NEXT:    li a1, -1
322 ; RV32ZBB-ZBP-ZBKB-NEXT:    bltz a3, .LBB15_2
323 ; RV32ZBB-ZBP-ZBKB-NEXT:  # %bb.1:
324 ; RV32ZBB-ZBP-ZBKB-NEXT:    rol a1, a2, a3
325 ; RV32ZBB-ZBP-ZBKB-NEXT:    li a0, -1
326 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
327 ; RV32ZBB-ZBP-ZBKB-NEXT:  .LBB15_2:
328 ; RV32ZBB-ZBP-ZBKB-NEXT:    rol a0, a2, a0
329 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
330   %1 = shl i64 1, %x
331   %2 = xor i64 %1, -1
332   ret i64 %2
335 define i8 @srli_i8(i8 %a) nounwind {
336 ; CHECK-LABEL: srli_i8:
337 ; CHECK:       # %bb.0:
338 ; CHECK-NEXT:    slli a0, a0, 24
339 ; CHECK-NEXT:    srli a0, a0, 30
340 ; CHECK-NEXT:    ret
341   %1 = lshr i8 %a, 6
342   ret i8 %1
345 ; We could use sext.b+srai, but slli+srai offers more opportunities for
346 ; comppressed instructions.
347 define i8 @srai_i8(i8 %a) nounwind {
348 ; CHECK-LABEL: srai_i8:
349 ; CHECK:       # %bb.0:
350 ; CHECK-NEXT:    slli a0, a0, 24
351 ; CHECK-NEXT:    srai a0, a0, 29
352 ; CHECK-NEXT:    ret
353   %1 = ashr i8 %a, 5
354   ret i8 %1
357 ; We could use zext.h+srli, but slli+srli offers more opportunities for
358 ; comppressed instructions.
359 define i16 @srli_i16(i16 %a) nounwind {
360 ; CHECK-LABEL: srli_i16:
361 ; CHECK:       # %bb.0:
362 ; CHECK-NEXT:    slli a0, a0, 16
363 ; CHECK-NEXT:    srli a0, a0, 22
364 ; CHECK-NEXT:    ret
365   %1 = lshr i16 %a, 6
366   ret i16 %1
369 ; We could use sext.h+srai, but slli+srai offers more opportunities for
370 ; comppressed instructions.
371 define i16 @srai_i16(i16 %a) nounwind {
372 ; CHECK-LABEL: srai_i16:
373 ; CHECK:       # %bb.0:
374 ; CHECK-NEXT:    slli a0, a0, 16
375 ; CHECK-NEXT:    srai a0, a0, 25
376 ; CHECK-NEXT:    ret
377   %1 = ashr i16 %a, 9
378   ret i16 %1
381 define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
382 ; RV32I-LABEL: andn_seqz_i32:
383 ; RV32I:       # %bb.0:
384 ; RV32I-NEXT:    and a0, a0, a1
385 ; RV32I-NEXT:    xor a0, a0, a1
386 ; RV32I-NEXT:    seqz a0, a0
387 ; RV32I-NEXT:    ret
389 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_seqz_i32:
390 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
391 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a1, a0
392 ; RV32ZBB-ZBP-ZBKB-NEXT:    seqz a0, a0
393 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
394   %and = and i32 %a, %b
395   %cmpeq = icmp eq i32 %and, %b
396   ret i1 %cmpeq
399 define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
400 ; RV32I-LABEL: andn_seqz_i64:
401 ; RV32I:       # %bb.0:
402 ; RV32I-NEXT:    not a0, a0
403 ; RV32I-NEXT:    not a1, a1
404 ; RV32I-NEXT:    and a1, a1, a3
405 ; RV32I-NEXT:    and a0, a0, a2
406 ; RV32I-NEXT:    or a0, a0, a1
407 ; RV32I-NEXT:    seqz a0, a0
408 ; RV32I-NEXT:    ret
410 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_seqz_i64:
411 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
412 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a1, a3, a1
413 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a2, a0
414 ; RV32ZBB-ZBP-ZBKB-NEXT:    or a0, a0, a1
415 ; RV32ZBB-ZBP-ZBKB-NEXT:    seqz a0, a0
416 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
417   %and = and i64 %a, %b
418   %cmpeq = icmp eq i64 %and, %b
419   ret i1 %cmpeq
422 define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
423 ; RV32I-LABEL: andn_snez_i32:
424 ; RV32I:       # %bb.0:
425 ; RV32I-NEXT:    and a0, a0, a1
426 ; RV32I-NEXT:    xor a0, a0, a1
427 ; RV32I-NEXT:    snez a0, a0
428 ; RV32I-NEXT:    ret
430 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_snez_i32:
431 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
432 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a1, a0
433 ; RV32ZBB-ZBP-ZBKB-NEXT:    snez a0, a0
434 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
435   %and = and i32 %a, %b
436   %cmpeq = icmp ne i32 %and, %b
437   ret i1 %cmpeq
440 define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
441 ; RV32I-LABEL: andn_snez_i64:
442 ; RV32I:       # %bb.0:
443 ; RV32I-NEXT:    not a0, a0
444 ; RV32I-NEXT:    not a1, a1
445 ; RV32I-NEXT:    and a1, a1, a3
446 ; RV32I-NEXT:    and a0, a0, a2
447 ; RV32I-NEXT:    or a0, a0, a1
448 ; RV32I-NEXT:    snez a0, a0
449 ; RV32I-NEXT:    ret
451 ; RV32ZBB-ZBP-ZBKB-LABEL: andn_snez_i64:
452 ; RV32ZBB-ZBP-ZBKB:       # %bb.0:
453 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a1, a3, a1
454 ; RV32ZBB-ZBP-ZBKB-NEXT:    andn a0, a2, a0
455 ; RV32ZBB-ZBP-ZBKB-NEXT:    or a0, a0, a1
456 ; RV32ZBB-ZBP-ZBKB-NEXT:    snez a0, a0
457 ; RV32ZBB-ZBP-ZBKB-NEXT:    ret
458   %and = and i64 %a, %b
459   %cmpeq = icmp ne i64 %and, %b
460   ret i1 %cmpeq