Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv32zbb-zbkb.ll
blob4e958f5699adbfa962c18ff03ff0d66eafb342bf
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:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    not a1, a1
13 ; RV32I-NEXT:    and a0, a1, a0
14 ; RV32I-NEXT:    ret
16 ; RV32ZBB-ZBKB-LABEL: andn_i32:
17 ; RV32ZBB-ZBKB:       # %bb.0:
18 ; RV32ZBB-ZBKB-NEXT:    andn a0, a0, a1
19 ; RV32ZBB-ZBKB-NEXT:    ret
20   %neg = xor i32 %b, -1
21   %and = and i32 %neg, %a
22   ret i32 %and
25 define i64 @andn_i64(i64 %a, i64 %b) nounwind {
26 ; RV32I-LABEL: andn_i64:
27 ; RV32I:       # %bb.0:
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
32 ; RV32I-NEXT:    ret
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
39   %neg = xor i64 %b, -1
40   %and = and i64 %neg, %a
41   ret i64 %and
44 define i32 @orn_i32(i32 %a, i32 %b) nounwind {
45 ; RV32I-LABEL: orn_i32:
46 ; RV32I:       # %bb.0:
47 ; RV32I-NEXT:    not a1, a1
48 ; RV32I-NEXT:    or a0, a1, a0
49 ; RV32I-NEXT:    ret
51 ; RV32ZBB-ZBKB-LABEL: orn_i32:
52 ; RV32ZBB-ZBKB:       # %bb.0:
53 ; RV32ZBB-ZBKB-NEXT:    orn a0, a0, a1
54 ; RV32ZBB-ZBKB-NEXT:    ret
55   %neg = xor i32 %b, -1
56   %or = or i32 %neg, %a
57   ret i32 %or
60 define i64 @orn_i64(i64 %a, i64 %b) nounwind {
61 ; RV32I-LABEL: orn_i64:
62 ; RV32I:       # %bb.0:
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
67 ; RV32I-NEXT:    ret
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
74   %neg = xor i64 %b, -1
75   %or = or i64 %neg, %a
76   ret i64 %or
79 define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
80 ; RV32I-LABEL: xnor_i32:
81 ; RV32I:       # %bb.0:
82 ; RV32I-NEXT:    xor a0, a0, a1
83 ; RV32I-NEXT:    not a0, a0
84 ; RV32I-NEXT:    ret
86 ; RV32ZBB-ZBKB-LABEL: xnor_i32:
87 ; RV32ZBB-ZBKB:       # %bb.0:
88 ; RV32ZBB-ZBKB-NEXT:    xnor a0, a0, a1
89 ; RV32ZBB-ZBKB-NEXT:    ret
90   %neg = xor i32 %a, -1
91   %xor = xor i32 %neg, %b
92   ret i32 %xor
95 define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
96 ; RV32I-LABEL: xnor_i64:
97 ; RV32I:       # %bb.0:
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
102 ; RV32I-NEXT:    ret
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
111   ret i64 %xor
114 declare i32 @llvm.fshl.i32(i32, i32, i32)
116 define i32 @rol_i32(i32 %a, i32 %b) nounwind {
117 ; RV32I-LABEL: rol_i32:
118 ; RV32I:       # %bb.0:
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
123 ; RV32I-NEXT:    ret
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)
130   ret i32 %or
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:
140 ; CHECK:       # %bb.0:
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
162 ; CHECK-NEXT:    ret
163   %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
164   ret i64 %or
167 declare i32 @llvm.fshr.i32(i32, i32, i32)
169 define i32 @ror_i32(i32 %a, i32 %b) nounwind {
170 ; RV32I-LABEL: ror_i32:
171 ; RV32I:       # %bb.0:
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
176 ; RV32I-NEXT:    ret
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)
183   ret i32 %or
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:
193 ; CHECK:       # %bb.0:
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
213 ; CHECK-NEXT:    ret
214   %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
215   ret i64 %or
218 define i32 @rori_i32_fshl(i32 %a) nounwind {
219 ; RV32I-LABEL: rori_i32_fshl:
220 ; RV32I:       # %bb.0:
221 ; RV32I-NEXT:    srli a1, a0, 1
222 ; RV32I-NEXT:    slli a0, a0, 31
223 ; RV32I-NEXT:    or a0, a0, a1
224 ; RV32I-NEXT:    ret
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)
231   ret i32 %1
234 define i32 @rori_i32_fshr(i32 %a) nounwind {
235 ; RV32I-LABEL: rori_i32_fshr:
236 ; RV32I:       # %bb.0:
237 ; RV32I-NEXT:    slli a1, a0, 1
238 ; RV32I-NEXT:    srli a0, a0, 31
239 ; RV32I-NEXT:    or a0, a0, a1
240 ; RV32I-NEXT:    ret
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)
247   ret i32 %1
250 define i64 @rori_i64(i64 %a) nounwind {
251 ; CHECK-LABEL: rori_i64:
252 ; CHECK:       # %bb.0:
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
260 ; CHECK-NEXT:    ret
261   %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
262   ret i64 %1
265 define i64 @rori_i64_fshr(i64 %a) nounwind {
266 ; CHECK-LABEL: rori_i64_fshr:
267 ; CHECK:       # %bb.0:
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
275 ; CHECK-NEXT:    ret
276   %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
277   ret i64 %1
280 define i32 @not_shl_one_i32(i32 %x) {
281 ; RV32I-LABEL: not_shl_one_i32:
282 ; RV32I:       # %bb.0:
283 ; RV32I-NEXT:    li a1, 1
284 ; RV32I-NEXT:    sll a0, a1, a0
285 ; RV32I-NEXT:    not a0, a0
286 ; RV32I-NEXT:    ret
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
293   %1 = shl i32 1, %x
294   %2 = xor i32 %1, -1
295   ret i32 %2
298 define i64 @not_shl_one_i64(i64 %x) {
299 ; CHECK-LABEL: not_shl_one_i64:
300 ; CHECK:       # %bb.0:
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
311 ; CHECK-NEXT:    ret
312   %1 = shl i64 1, %x
313   %2 = xor i64 %1, -1
314   ret i64 %2
317 define i8 @srli_i8(i8 %a) nounwind {
318 ; CHECK-LABEL: srli_i8:
319 ; CHECK:       # %bb.0:
320 ; CHECK-NEXT:    slli a0, a0, 24
321 ; CHECK-NEXT:    srli a0, a0, 30
322 ; CHECK-NEXT:    ret
323   %1 = lshr i8 %a, 6
324   ret i8 %1
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:
331 ; CHECK:       # %bb.0:
332 ; CHECK-NEXT:    slli a0, a0, 24
333 ; CHECK-NEXT:    srai a0, a0, 29
334 ; CHECK-NEXT:    ret
335   %1 = ashr i8 %a, 5
336   ret i8 %1
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:
343 ; CHECK:       # %bb.0:
344 ; CHECK-NEXT:    slli a0, a0, 16
345 ; CHECK-NEXT:    srli a0, a0, 22
346 ; CHECK-NEXT:    ret
347   %1 = lshr i16 %a, 6
348   ret i16 %1
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:
355 ; CHECK:       # %bb.0:
356 ; CHECK-NEXT:    slli a0, a0, 16
357 ; CHECK-NEXT:    srai a0, a0, 25
358 ; CHECK-NEXT:    ret
359   %1 = ashr i16 %a, 9
360   ret i16 %1
363 define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
364 ; RV32I-LABEL: andn_seqz_i32:
365 ; RV32I:       # %bb.0:
366 ; RV32I-NEXT:    and a0, a0, a1
367 ; RV32I-NEXT:    xor a0, a0, a1
368 ; RV32I-NEXT:    seqz a0, a0
369 ; RV32I-NEXT:    ret
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
378   ret i1 %cmpeq
381 define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
382 ; RV32I-LABEL: andn_seqz_i64:
383 ; RV32I:       # %bb.0:
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
390 ; RV32I-NEXT:    ret
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
401   ret i1 %cmpeq
404 define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
405 ; RV32I-LABEL: andn_snez_i32:
406 ; RV32I:       # %bb.0:
407 ; RV32I-NEXT:    and a0, a0, a1
408 ; RV32I-NEXT:    xor a0, a0, a1
409 ; RV32I-NEXT:    snez a0, a0
410 ; RV32I-NEXT:    ret
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
419   ret i1 %cmpeq
422 define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
423 ; RV32I-LABEL: andn_snez_i64:
424 ; RV32I:       # %bb.0:
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
431 ; RV32I-NEXT:    ret
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
442   ret i1 %cmpeq