[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv32zbs.ll
blob1a3beeb79b85bd5bd2a1a5c25c4a71860c5d3f93
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=+zbs -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBS,RV32ZBSNOZBB
6 ; RUN: llc -mtriple=riscv32 -mattr=+zbs,+zbb -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBS,RV32ZBSZBB
9 define i32 @bclr_i32(i32 %a, i32 %b) nounwind {
10 ; RV32I-LABEL: bclr_i32:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    li a2, 1
13 ; RV32I-NEXT:    sll a1, a2, a1
14 ; RV32I-NEXT:    not a1, a1
15 ; RV32I-NEXT:    and a0, a1, a0
16 ; RV32I-NEXT:    ret
18 ; RV32ZBS-LABEL: bclr_i32:
19 ; RV32ZBS:       # %bb.0:
20 ; RV32ZBS-NEXT:    bclr a0, a0, a1
21 ; RV32ZBS-NEXT:    ret
22   %and = and i32 %b, 31
23   %shl = shl nuw i32 1, %and
24   %neg = xor i32 %shl, -1
25   %and1 = and i32 %neg, %a
26   ret i32 %and1
29 define i32 @bclr_i32_no_mask(i32 %a, i32 %b) nounwind {
30 ; RV32I-LABEL: bclr_i32_no_mask:
31 ; RV32I:       # %bb.0:
32 ; RV32I-NEXT:    li a2, 1
33 ; RV32I-NEXT:    sll a1, a2, a1
34 ; RV32I-NEXT:    not a1, a1
35 ; RV32I-NEXT:    and a0, a1, a0
36 ; RV32I-NEXT:    ret
38 ; RV32ZBS-LABEL: bclr_i32_no_mask:
39 ; RV32ZBS:       # %bb.0:
40 ; RV32ZBS-NEXT:    bclr a0, a0, a1
41 ; RV32ZBS-NEXT:    ret
42   %shl = shl nuw i32 1, %b
43   %neg = xor i32 %shl, -1
44   %and1 = and i32 %neg, %a
45   ret i32 %and1
48 define i64 @bclr_i64(i64 %a, i64 %b) nounwind {
49 ; RV32I-LABEL: bclr_i64:
50 ; RV32I:       # %bb.0:
51 ; RV32I-NEXT:    andi a3, a2, 63
52 ; RV32I-NEXT:    li a4, 1
53 ; RV32I-NEXT:    addi a5, a3, -32
54 ; RV32I-NEXT:    sll a2, a4, a2
55 ; RV32I-NEXT:    sll a3, a4, a3
56 ; RV32I-NEXT:    slti a4, a5, 0
57 ; RV32I-NEXT:    neg a5, a4
58 ; RV32I-NEXT:    addi a4, a4, -1
59 ; RV32I-NEXT:    and a2, a5, a2
60 ; RV32I-NEXT:    and a3, a4, a3
61 ; RV32I-NEXT:    not a2, a2
62 ; RV32I-NEXT:    not a3, a3
63 ; RV32I-NEXT:    and a0, a2, a0
64 ; RV32I-NEXT:    and a1, a3, a1
65 ; RV32I-NEXT:    ret
67 ; RV32ZBSNOZBB-LABEL: bclr_i64:
68 ; RV32ZBSNOZBB:       # %bb.0:
69 ; RV32ZBSNOZBB-NEXT:    andi a3, a2, 63
70 ; RV32ZBSNOZBB-NEXT:    bset a2, zero, a2
71 ; RV32ZBSNOZBB-NEXT:    addi a4, a3, -32
72 ; RV32ZBSNOZBB-NEXT:    bset a3, zero, a3
73 ; RV32ZBSNOZBB-NEXT:    slti a4, a4, 0
74 ; RV32ZBSNOZBB-NEXT:    neg a5, a4
75 ; RV32ZBSNOZBB-NEXT:    addi a4, a4, -1
76 ; RV32ZBSNOZBB-NEXT:    and a2, a5, a2
77 ; RV32ZBSNOZBB-NEXT:    and a3, a4, a3
78 ; RV32ZBSNOZBB-NEXT:    not a3, a3
79 ; RV32ZBSNOZBB-NEXT:    not a2, a2
80 ; RV32ZBSNOZBB-NEXT:    and a0, a2, a0
81 ; RV32ZBSNOZBB-NEXT:    and a1, a3, a1
82 ; RV32ZBSNOZBB-NEXT:    ret
84 ; RV32ZBSZBB-LABEL: bclr_i64:
85 ; RV32ZBSZBB:       # %bb.0:
86 ; RV32ZBSZBB-NEXT:    andi a3, a2, 63
87 ; RV32ZBSZBB-NEXT:    bset a2, zero, a2
88 ; RV32ZBSZBB-NEXT:    bset a4, zero, a3
89 ; RV32ZBSZBB-NEXT:    addi a3, a3, -32
90 ; RV32ZBSZBB-NEXT:    slti a3, a3, 0
91 ; RV32ZBSZBB-NEXT:    addi a5, a3, -1
92 ; RV32ZBSZBB-NEXT:    neg a3, a3
93 ; RV32ZBSZBB-NEXT:    and a4, a5, a4
94 ; RV32ZBSZBB-NEXT:    and a2, a3, a2
95 ; RV32ZBSZBB-NEXT:    andn a0, a0, a2
96 ; RV32ZBSZBB-NEXT:    andn a1, a1, a4
97 ; RV32ZBSZBB-NEXT:    ret
98   %and = and i64 %b, 63
99   %shl = shl nuw i64 1, %and
100   %neg = xor i64 %shl, -1
101   %and1 = and i64 %neg, %a
102   ret i64 %and1
105 define i32 @bset_i32(i32 %a, i32 %b) nounwind {
106 ; RV32I-LABEL: bset_i32:
107 ; RV32I:       # %bb.0:
108 ; RV32I-NEXT:    li a2, 1
109 ; RV32I-NEXT:    sll a1, a2, a1
110 ; RV32I-NEXT:    or a0, a1, a0
111 ; RV32I-NEXT:    ret
113 ; RV32ZBS-LABEL: bset_i32:
114 ; RV32ZBS:       # %bb.0:
115 ; RV32ZBS-NEXT:    bset a0, a0, a1
116 ; RV32ZBS-NEXT:    ret
117   %and = and i32 %b, 31
118   %shl = shl nuw i32 1, %and
119   %or = or i32 %shl, %a
120   ret i32 %or
123 define i32 @bset_i32_no_mask(i32 %a, i32 %b) nounwind {
124 ; RV32I-LABEL: bset_i32_no_mask:
125 ; RV32I:       # %bb.0:
126 ; RV32I-NEXT:    li a2, 1
127 ; RV32I-NEXT:    sll a1, a2, a1
128 ; RV32I-NEXT:    or a0, a1, a0
129 ; RV32I-NEXT:    ret
131 ; RV32ZBS-LABEL: bset_i32_no_mask:
132 ; RV32ZBS:       # %bb.0:
133 ; RV32ZBS-NEXT:    bset a0, a0, a1
134 ; RV32ZBS-NEXT:    ret
135   %shl = shl nuw i32 1, %b
136   %or = or i32 %shl, %a
137   ret i32 %or
140 ; We can use bsetw for 1 << x by setting the first source to zero.
141 define signext i32 @bset_i32_zero(i32 signext %a) nounwind {
142 ; RV32I-LABEL: bset_i32_zero:
143 ; RV32I:       # %bb.0:
144 ; RV32I-NEXT:    li a1, 1
145 ; RV32I-NEXT:    sll a0, a1, a0
146 ; RV32I-NEXT:    ret
148 ; RV32ZBS-LABEL: bset_i32_zero:
149 ; RV32ZBS:       # %bb.0:
150 ; RV32ZBS-NEXT:    bset a0, zero, a0
151 ; RV32ZBS-NEXT:    ret
152   %shl = shl i32 1, %a
153   ret i32 %shl
156 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
157 ; don't have yet any matching bit manipulation instructions on RV32.
158 ; This test is presented here in case future expansions of the Bitmanip
159 ; extensions introduce instructions suitable for this pattern.
161 define i64 @bset_i64(i64 %a, i64 %b) nounwind {
162 ; RV32I-LABEL: bset_i64:
163 ; RV32I:       # %bb.0:
164 ; RV32I-NEXT:    li a3, 1
165 ; RV32I-NEXT:    sll a2, a3, a2
166 ; RV32I-NEXT:    srai a3, a2, 31
167 ; RV32I-NEXT:    or a0, a2, a0
168 ; RV32I-NEXT:    or a1, a3, a1
169 ; RV32I-NEXT:    ret
171 ; RV32ZBS-LABEL: bset_i64:
172 ; RV32ZBS:       # %bb.0:
173 ; RV32ZBS-NEXT:    bset a3, zero, a2
174 ; RV32ZBS-NEXT:    srai a3, a3, 31
175 ; RV32ZBS-NEXT:    bset a0, a0, a2
176 ; RV32ZBS-NEXT:    or a1, a3, a1
177 ; RV32ZBS-NEXT:    ret
178   %1 = trunc i64 %b to i32
179   %conv = and i32 %1, 63
180   %shl = shl nuw i32 1, %conv
181   %conv1 = sext i32 %shl to i64
182   %or = or i64 %conv1, %a
183   ret i64 %or
186 define signext i64 @bset_i64_zero(i64 signext %a) nounwind {
187 ; RV32I-LABEL: bset_i64_zero:
188 ; RV32I:       # %bb.0:
189 ; RV32I-NEXT:    addi a1, a0, -32
190 ; RV32I-NEXT:    li a2, 1
191 ; RV32I-NEXT:    slti a1, a1, 0
192 ; RV32I-NEXT:    sll a2, a2, a0
193 ; RV32I-NEXT:    neg a0, a1
194 ; RV32I-NEXT:    addi a1, a1, -1
195 ; RV32I-NEXT:    and a0, a0, a2
196 ; RV32I-NEXT:    and a1, a1, a2
197 ; RV32I-NEXT:    ret
199 ; RV32ZBS-LABEL: bset_i64_zero:
200 ; RV32ZBS:       # %bb.0:
201 ; RV32ZBS-NEXT:    addi a1, a0, -32
202 ; RV32ZBS-NEXT:    bset a2, zero, a0
203 ; RV32ZBS-NEXT:    slti a0, a1, 0
204 ; RV32ZBS-NEXT:    neg a1, a0
205 ; RV32ZBS-NEXT:    addi a3, a0, -1
206 ; RV32ZBS-NEXT:    and a0, a1, a2
207 ; RV32ZBS-NEXT:    and a1, a3, a2
208 ; RV32ZBS-NEXT:    ret
209   %shl = shl i64 1, %a
210   ret i64 %shl
213 define i32 @binv_i32(i32 %a, i32 %b) nounwind {
214 ; RV32I-LABEL: binv_i32:
215 ; RV32I:       # %bb.0:
216 ; RV32I-NEXT:    li a2, 1
217 ; RV32I-NEXT:    sll a1, a2, a1
218 ; RV32I-NEXT:    xor a0, a1, a0
219 ; RV32I-NEXT:    ret
221 ; RV32ZBS-LABEL: binv_i32:
222 ; RV32ZBS:       # %bb.0:
223 ; RV32ZBS-NEXT:    binv a0, a0, a1
224 ; RV32ZBS-NEXT:    ret
225   %and = and i32 %b, 31
226   %shl = shl nuw i32 1, %and
227   %xor = xor i32 %shl, %a
228   ret i32 %xor
231 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
232 ; don't have yet any matching bit manipulation instructions on RV32.
233 ; This test is presented here in case future expansions of the Bitmanip
234 ; extensions introduce instructions suitable for this pattern.
236 define i64 @binv_i64(i64 %a, i64 %b) nounwind {
237 ; RV32I-LABEL: binv_i64:
238 ; RV32I:       # %bb.0:
239 ; RV32I-NEXT:    li a3, 1
240 ; RV32I-NEXT:    sll a2, a3, a2
241 ; RV32I-NEXT:    srai a3, a2, 31
242 ; RV32I-NEXT:    xor a0, a2, a0
243 ; RV32I-NEXT:    xor a1, a3, a1
244 ; RV32I-NEXT:    ret
246 ; RV32ZBS-LABEL: binv_i64:
247 ; RV32ZBS:       # %bb.0:
248 ; RV32ZBS-NEXT:    bset a3, zero, a2
249 ; RV32ZBS-NEXT:    srai a3, a3, 31
250 ; RV32ZBS-NEXT:    binv a0, a0, a2
251 ; RV32ZBS-NEXT:    xor a1, a3, a1
252 ; RV32ZBS-NEXT:    ret
253   %1 = trunc i64 %b to i32
254   %conv = and i32 %1, 63
255   %shl = shl nuw i32 1, %conv
256   %conv1 = sext i32 %shl to i64
257   %xor = xor i64 %conv1, %a
258   ret i64 %xor
261 define i32 @bext_i32(i32 %a, i32 %b) nounwind {
262 ; RV32I-LABEL: bext_i32:
263 ; RV32I:       # %bb.0:
264 ; RV32I-NEXT:    srl a0, a0, a1
265 ; RV32I-NEXT:    andi a0, a0, 1
266 ; RV32I-NEXT:    ret
268 ; RV32ZBS-LABEL: bext_i32:
269 ; RV32ZBS:       # %bb.0:
270 ; RV32ZBS-NEXT:    bext a0, a0, a1
271 ; RV32ZBS-NEXT:    ret
272   %and = and i32 %b, 31
273   %shr = lshr i32 %a, %and
274   %and1 = and i32 %shr, 1
275   ret i32 %and1
278 define i32 @bext_i32_no_mask(i32 %a, i32 %b) nounwind {
279 ; RV32I-LABEL: bext_i32_no_mask:
280 ; RV32I:       # %bb.0:
281 ; RV32I-NEXT:    srl a0, a0, a1
282 ; RV32I-NEXT:    andi a0, a0, 1
283 ; RV32I-NEXT:    ret
285 ; RV32ZBS-LABEL: bext_i32_no_mask:
286 ; RV32ZBS:       # %bb.0:
287 ; RV32ZBS-NEXT:    bext a0, a0, a1
288 ; RV32ZBS-NEXT:    ret
289   %shr = lshr i32 %a, %b
290   %and1 = and i32 %shr, 1
291   ret i32 %and1
294 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
295 ; don't have yet any matching bit manipulation instructions on RV32.
296 ; This test is presented here in case future expansions of the Bitmanip
297 ; extensions introduce instructions suitable for this pattern.
299 define i64 @bext_i64(i64 %a, i64 %b) nounwind {
300 ; CHECK-LABEL: bext_i64:
301 ; CHECK:       # %bb.0:
302 ; CHECK-NEXT:    andi a3, a2, 63
303 ; CHECK-NEXT:    addi a4, a3, -32
304 ; CHECK-NEXT:    bltz a4, .LBB12_2
305 ; CHECK-NEXT:  # %bb.1:
306 ; CHECK-NEXT:    srl a0, a1, a3
307 ; CHECK-NEXT:    j .LBB12_3
308 ; CHECK-NEXT:  .LBB12_2:
309 ; CHECK-NEXT:    srl a0, a0, a2
310 ; CHECK-NEXT:    slli a1, a1, 1
311 ; CHECK-NEXT:    not a2, a3
312 ; CHECK-NEXT:    sll a1, a1, a2
313 ; CHECK-NEXT:    or a0, a0, a1
314 ; CHECK-NEXT:  .LBB12_3:
315 ; CHECK-NEXT:    andi a0, a0, 1
316 ; CHECK-NEXT:    li a1, 0
317 ; CHECK-NEXT:    ret
318   %conv = and i64 %b, 63
319   %shr = lshr i64 %a, %conv
320   %and1 = and i64 %shr, 1
321   ret i64 %and1
324 define i32 @bexti_i32(i32 %a) nounwind {
325 ; RV32I-LABEL: bexti_i32:
326 ; RV32I:       # %bb.0:
327 ; RV32I-NEXT:    slli a0, a0, 26
328 ; RV32I-NEXT:    srli a0, a0, 31
329 ; RV32I-NEXT:    ret
331 ; RV32ZBS-LABEL: bexti_i32:
332 ; RV32ZBS:       # %bb.0:
333 ; RV32ZBS-NEXT:    bexti a0, a0, 5
334 ; RV32ZBS-NEXT:    ret
335   %shr = lshr i32 %a, 5
336   %and = and i32 %shr, 1
337   ret i32 %and
340 define i64 @bexti_i64(i64 %a) nounwind {
341 ; RV32I-LABEL: bexti_i64:
342 ; RV32I:       # %bb.0:
343 ; RV32I-NEXT:    slli a0, a0, 26
344 ; RV32I-NEXT:    srli a0, a0, 31
345 ; RV32I-NEXT:    li a1, 0
346 ; RV32I-NEXT:    ret
348 ; RV32ZBS-LABEL: bexti_i64:
349 ; RV32ZBS:       # %bb.0:
350 ; RV32ZBS-NEXT:    bexti a0, a0, 5
351 ; RV32ZBS-NEXT:    li a1, 0
352 ; RV32ZBS-NEXT:    ret
353   %shr = lshr i64 %a, 5
354   %and = and i64 %shr, 1
355   ret i64 %and
358 define signext i32 @bexti_i32_cmp(i32 signext %a) nounwind {
359 ; RV32I-LABEL: bexti_i32_cmp:
360 ; RV32I:       # %bb.0:
361 ; RV32I-NEXT:    slli a0, a0, 26
362 ; RV32I-NEXT:    srli a0, a0, 31
363 ; RV32I-NEXT:    ret
365 ; RV32ZBS-LABEL: bexti_i32_cmp:
366 ; RV32ZBS:       # %bb.0:
367 ; RV32ZBS-NEXT:    bexti a0, a0, 5
368 ; RV32ZBS-NEXT:    ret
369   %and = and i32 %a, 32
370   %cmp = icmp ne i32 %and, 0
371   %zext = zext i1 %cmp to i32
372   ret i32 %zext
375 define i64 @bexti_i64_cmp(i64 %a) nounwind {
376 ; RV32I-LABEL: bexti_i64_cmp:
377 ; RV32I:       # %bb.0:
378 ; RV32I-NEXT:    slli a0, a0, 26
379 ; RV32I-NEXT:    srli a0, a0, 31
380 ; RV32I-NEXT:    li a1, 0
381 ; RV32I-NEXT:    ret
383 ; RV32ZBS-LABEL: bexti_i64_cmp:
384 ; RV32ZBS:       # %bb.0:
385 ; RV32ZBS-NEXT:    bexti a0, a0, 5
386 ; RV32ZBS-NEXT:    li a1, 0
387 ; RV32ZBS-NEXT:    ret
388   %and = and i64 %a, 32
389   %cmp = icmp ne i64 %and, 0
390   %zext = zext i1 %cmp to i64
391   ret i64 %zext
394 define i32 @bclri_i32_10(i32 %a) nounwind {
395 ; CHECK-LABEL: bclri_i32_10:
396 ; CHECK:       # %bb.0:
397 ; CHECK-NEXT:    andi a0, a0, -1025
398 ; CHECK-NEXT:    ret
399   %and = and i32 %a, -1025
400   ret i32 %and
403 define i32 @bclri_i32_11(i32 %a) nounwind {
404 ; RV32I-LABEL: bclri_i32_11:
405 ; RV32I:       # %bb.0:
406 ; RV32I-NEXT:    lui a1, 1048575
407 ; RV32I-NEXT:    addi a1, a1, 2047
408 ; RV32I-NEXT:    and a0, a0, a1
409 ; RV32I-NEXT:    ret
411 ; RV32ZBS-LABEL: bclri_i32_11:
412 ; RV32ZBS:       # %bb.0:
413 ; RV32ZBS-NEXT:    bclri a0, a0, 11
414 ; RV32ZBS-NEXT:    ret
415   %and = and i32 %a, -2049
416   ret i32 %and
419 define i32 @bclri_i32_30(i32 %a) nounwind {
420 ; RV32I-LABEL: bclri_i32_30:
421 ; RV32I:       # %bb.0:
422 ; RV32I-NEXT:    lui a1, 786432
423 ; RV32I-NEXT:    addi a1, a1, -1
424 ; RV32I-NEXT:    and a0, a0, a1
425 ; RV32I-NEXT:    ret
427 ; RV32ZBS-LABEL: bclri_i32_30:
428 ; RV32ZBS:       # %bb.0:
429 ; RV32ZBS-NEXT:    bclri a0, a0, 30
430 ; RV32ZBS-NEXT:    ret
431   %and = and i32 %a, -1073741825
432   ret i32 %and
435 define i32 @bclri_i32_31(i32 %a) nounwind {
436 ; RV32I-LABEL: bclri_i32_31:
437 ; RV32I:       # %bb.0:
438 ; RV32I-NEXT:    slli a0, a0, 1
439 ; RV32I-NEXT:    srli a0, a0, 1
440 ; RV32I-NEXT:    ret
442 ; RV32ZBS-LABEL: bclri_i32_31:
443 ; RV32ZBS:       # %bb.0:
444 ; RV32ZBS-NEXT:    bclri a0, a0, 31
445 ; RV32ZBS-NEXT:    ret
446   %and = and i32 %a, -2147483649
447   ret i32 %and
450 define i32 @bclri_i32_large0(i32 %a) nounwind {
451 ; RV32I-LABEL: bclri_i32_large0:
452 ; RV32I:       # %bb.0:
453 ; RV32I-NEXT:    lui a1, 1044480
454 ; RV32I-NEXT:    addi a1, a1, -256
455 ; RV32I-NEXT:    and a0, a0, a1
456 ; RV32I-NEXT:    ret
458 ; RV32ZBS-LABEL: bclri_i32_large0:
459 ; RV32ZBS:       # %bb.0:
460 ; RV32ZBS-NEXT:    andi a0, a0, -256
461 ; RV32ZBS-NEXT:    bclri a0, a0, 24
462 ; RV32ZBS-NEXT:    ret
463   %and = and i32 %a, -16777472
464   ret i32 %and
467 define i32 @bclri_i32_large1(i32 %a) nounwind {
468 ; RV32I-LABEL: bclri_i32_large1:
469 ; RV32I:       # %bb.0:
470 ; RV32I-NEXT:    lui a1, 1044464
471 ; RV32I-NEXT:    addi a1, a1, -1
472 ; RV32I-NEXT:    and a0, a0, a1
473 ; RV32I-NEXT:    ret
475 ; RV32ZBS-LABEL: bclri_i32_large1:
476 ; RV32ZBS:       # %bb.0:
477 ; RV32ZBS-NEXT:    bclri a0, a0, 16
478 ; RV32ZBS-NEXT:    bclri a0, a0, 24
479 ; RV32ZBS-NEXT:    ret
480   %and = and i32 %a, -16842753
481   ret i32 %and
484 define i32 @bclri_i32_large2(i32 %0) {
485 ; RV32I-LABEL: bclri_i32_large2:
486 ; RV32I:       # %bb.0:
487 ; RV32I-NEXT:    lui a1, 524288
488 ; RV32I-NEXT:    addi a1, a1, -5
489 ; RV32I-NEXT:    and a0, a0, a1
490 ; RV32I-NEXT:    ret
492 ; RV32ZBS-LABEL: bclri_i32_large2:
493 ; RV32ZBS:       # %bb.0:
494 ; RV32ZBS-NEXT:    bclri a0, a0, 2
495 ; RV32ZBS-NEXT:    bclri a0, a0, 31
496 ; RV32ZBS-NEXT:    ret
497   %2 = and i32 %0, 2147483643
498   ret i32 %2
501 define i32 @bclri_i32_large3(i32 %0) {
502 ; RV32I-LABEL: bclri_i32_large3:
503 ; RV32I:       # %bb.0:
504 ; RV32I-NEXT:    lui a1, 524288
505 ; RV32I-NEXT:    addi a1, a1, -6
506 ; RV32I-NEXT:    and a0, a0, a1
507 ; RV32I-NEXT:    ret
509 ; RV32ZBS-LABEL: bclri_i32_large3:
510 ; RV32ZBS:       # %bb.0:
511 ; RV32ZBS-NEXT:    andi a0, a0, -6
512 ; RV32ZBS-NEXT:    bclri a0, a0, 31
513 ; RV32ZBS-NEXT:    ret
514   %2 = and i32 %0, 2147483642
515   ret i32 %2
518 define i32 @bseti_i32_10(i32 %a) nounwind {
519 ; CHECK-LABEL: bseti_i32_10:
520 ; CHECK:       # %bb.0:
521 ; CHECK-NEXT:    ori a0, a0, 1024
522 ; CHECK-NEXT:    ret
523   %or = or i32 %a, 1024
524   ret i32 %or
527 define i32 @bseti_i32_11(i32 %a) nounwind {
528 ; RV32I-LABEL: bseti_i32_11:
529 ; RV32I:       # %bb.0:
530 ; RV32I-NEXT:    li a1, 1
531 ; RV32I-NEXT:    slli a1, a1, 11
532 ; RV32I-NEXT:    or a0, a0, a1
533 ; RV32I-NEXT:    ret
535 ; RV32ZBS-LABEL: bseti_i32_11:
536 ; RV32ZBS:       # %bb.0:
537 ; RV32ZBS-NEXT:    bseti a0, a0, 11
538 ; RV32ZBS-NEXT:    ret
539   %or = or i32 %a, 2048
540   ret i32 %or
543 define i32 @bseti_i32_30(i32 %a) nounwind {
544 ; RV32I-LABEL: bseti_i32_30:
545 ; RV32I:       # %bb.0:
546 ; RV32I-NEXT:    lui a1, 262144
547 ; RV32I-NEXT:    or a0, a0, a1
548 ; RV32I-NEXT:    ret
550 ; RV32ZBS-LABEL: bseti_i32_30:
551 ; RV32ZBS:       # %bb.0:
552 ; RV32ZBS-NEXT:    bseti a0, a0, 30
553 ; RV32ZBS-NEXT:    ret
554   %or = or i32 %a, 1073741824
555   ret i32 %or
558 define i32 @bseti_i32_31(i32 %a) nounwind {
559 ; RV32I-LABEL: bseti_i32_31:
560 ; RV32I:       # %bb.0:
561 ; RV32I-NEXT:    lui a1, 524288
562 ; RV32I-NEXT:    or a0, a0, a1
563 ; RV32I-NEXT:    ret
565 ; RV32ZBS-LABEL: bseti_i32_31:
566 ; RV32ZBS:       # %bb.0:
567 ; RV32ZBS-NEXT:    bseti a0, a0, 31
568 ; RV32ZBS-NEXT:    ret
569   %or = or i32 %a, 2147483648
570   ret i32 %or
573 define i32 @binvi_i32_10(i32 %a) nounwind {
574 ; CHECK-LABEL: binvi_i32_10:
575 ; CHECK:       # %bb.0:
576 ; CHECK-NEXT:    xori a0, a0, 1024
577 ; CHECK-NEXT:    ret
578   %xor = xor i32 %a, 1024
579   ret i32 %xor
582 define i32 @binvi_i32_11(i32 %a) nounwind {
583 ; RV32I-LABEL: binvi_i32_11:
584 ; RV32I:       # %bb.0:
585 ; RV32I-NEXT:    li a1, 1
586 ; RV32I-NEXT:    slli a1, a1, 11
587 ; RV32I-NEXT:    xor a0, a0, a1
588 ; RV32I-NEXT:    ret
590 ; RV32ZBS-LABEL: binvi_i32_11:
591 ; RV32ZBS:       # %bb.0:
592 ; RV32ZBS-NEXT:    binvi a0, a0, 11
593 ; RV32ZBS-NEXT:    ret
594   %xor = xor i32 %a, 2048
595   ret i32 %xor
598 define i32 @binvi_i32_30(i32 %a) nounwind {
599 ; RV32I-LABEL: binvi_i32_30:
600 ; RV32I:       # %bb.0:
601 ; RV32I-NEXT:    lui a1, 262144
602 ; RV32I-NEXT:    xor a0, a0, a1
603 ; RV32I-NEXT:    ret
605 ; RV32ZBS-LABEL: binvi_i32_30:
606 ; RV32ZBS:       # %bb.0:
607 ; RV32ZBS-NEXT:    binvi a0, a0, 30
608 ; RV32ZBS-NEXT:    ret
609   %xor = xor i32 %a, 1073741824
610   ret i32 %xor
613 define i32 @binvi_i32_31(i32 %a) nounwind {
614 ; RV32I-LABEL: binvi_i32_31:
615 ; RV32I:       # %bb.0:
616 ; RV32I-NEXT:    lui a1, 524288
617 ; RV32I-NEXT:    xor a0, a0, a1
618 ; RV32I-NEXT:    ret
620 ; RV32ZBS-LABEL: binvi_i32_31:
621 ; RV32ZBS:       # %bb.0:
622 ; RV32ZBS-NEXT:    binvi a0, a0, 31
623 ; RV32ZBS-NEXT:    ret
624   %xor = xor i32 %a, 2147483648
625   ret i32 %xor
628 define i32 @xor_i32_4098(i32 %a) nounwind {
629 ; RV32I-LABEL: xor_i32_4098:
630 ; RV32I:       # %bb.0:
631 ; RV32I-NEXT:    lui a1, 1
632 ; RV32I-NEXT:    addi a1, a1, 2
633 ; RV32I-NEXT:    xor a0, a0, a1
634 ; RV32I-NEXT:    ret
636 ; RV32ZBS-LABEL: xor_i32_4098:
637 ; RV32ZBS:       # %bb.0:
638 ; RV32ZBS-NEXT:    binvi a0, a0, 1
639 ; RV32ZBS-NEXT:    binvi a0, a0, 12
640 ; RV32ZBS-NEXT:    ret
641   %xor = xor i32 %a, 4098
642   ret i32 %xor
645 define i32 @xor_i32_4099(i32 %a) nounwind {
646 ; RV32I-LABEL: xor_i32_4099:
647 ; RV32I:       # %bb.0:
648 ; RV32I-NEXT:    lui a1, 1
649 ; RV32I-NEXT:    addi a1, a1, 3
650 ; RV32I-NEXT:    xor a0, a0, a1
651 ; RV32I-NEXT:    ret
653 ; RV32ZBS-LABEL: xor_i32_4099:
654 ; RV32ZBS:       # %bb.0:
655 ; RV32ZBS-NEXT:    xori a0, a0, 3
656 ; RV32ZBS-NEXT:    binvi a0, a0, 12
657 ; RV32ZBS-NEXT:    ret
658   %xor = xor i32 %a, 4099
659   ret i32 %xor
662 define i32 @xor_i32_96(i32 %a) nounwind {
663 ; CHECK-LABEL: xor_i32_96:
664 ; CHECK:       # %bb.0:
665 ; CHECK-NEXT:    xori a0, a0, 96
666 ; CHECK-NEXT:    ret
667   %xor = xor i32 %a, 96
668   ret i32 %xor
671 define i32 @xor_i32_66901(i32 %a) nounwind {
672 ; RV32I-LABEL: xor_i32_66901:
673 ; RV32I:       # %bb.0:
674 ; RV32I-NEXT:    lui a1, 16
675 ; RV32I-NEXT:    addi a1, a1, 1365
676 ; RV32I-NEXT:    xor a0, a0, a1
677 ; RV32I-NEXT:    ret
679 ; RV32ZBS-LABEL: xor_i32_66901:
680 ; RV32ZBS:       # %bb.0:
681 ; RV32ZBS-NEXT:    xori a0, a0, 1365
682 ; RV32ZBS-NEXT:    binvi a0, a0, 16
683 ; RV32ZBS-NEXT:    ret
684   %xor = xor i32 %a, 66901
685   ret i32 %xor
688 define i32 @or_i32_4098(i32 %a) nounwind {
689 ; RV32I-LABEL: or_i32_4098:
690 ; RV32I:       # %bb.0:
691 ; RV32I-NEXT:    lui a1, 1
692 ; RV32I-NEXT:    addi a1, a1, 2
693 ; RV32I-NEXT:    or a0, a0, a1
694 ; RV32I-NEXT:    ret
696 ; RV32ZBS-LABEL: or_i32_4098:
697 ; RV32ZBS:       # %bb.0:
698 ; RV32ZBS-NEXT:    bseti a0, a0, 1
699 ; RV32ZBS-NEXT:    bseti a0, a0, 12
700 ; RV32ZBS-NEXT:    ret
701   %or = or i32 %a, 4098
702   ret i32 %or
705 define i32 @or_i32_4099(i32 %a) nounwind {
706 ; RV32I-LABEL: or_i32_4099:
707 ; RV32I:       # %bb.0:
708 ; RV32I-NEXT:    lui a1, 1
709 ; RV32I-NEXT:    addi a1, a1, 3
710 ; RV32I-NEXT:    or a0, a0, a1
711 ; RV32I-NEXT:    ret
713 ; RV32ZBS-LABEL: or_i32_4099:
714 ; RV32ZBS:       # %bb.0:
715 ; RV32ZBS-NEXT:    ori a0, a0, 3
716 ; RV32ZBS-NEXT:    bseti a0, a0, 12
717 ; RV32ZBS-NEXT:    ret
718   %or = or i32 %a, 4099
719   ret i32 %or
722 define i32 @or_i32_96(i32 %a) nounwind {
723 ; CHECK-LABEL: or_i32_96:
724 ; CHECK:       # %bb.0:
725 ; CHECK-NEXT:    ori a0, a0, 96
726 ; CHECK-NEXT:    ret
727   %or = or i32 %a, 96
728   ret i32 %or
731 define i32 @or_i32_66901(i32 %a) nounwind {
732 ; RV32I-LABEL: or_i32_66901:
733 ; RV32I:       # %bb.0:
734 ; RV32I-NEXT:    lui a1, 16
735 ; RV32I-NEXT:    addi a1, a1, 1365
736 ; RV32I-NEXT:    or a0, a0, a1
737 ; RV32I-NEXT:    ret
739 ; RV32ZBS-LABEL: or_i32_66901:
740 ; RV32ZBS:       # %bb.0:
741 ; RV32ZBS-NEXT:    ori a0, a0, 1365
742 ; RV32ZBS-NEXT:    bseti a0, a0, 16
743 ; RV32ZBS-NEXT:    ret
744   %or = or i32 %a, 66901
745   ret i32 %or
748 define i32 @bset_trailing_ones_i32_mask(i32 %a) nounwind {
749 ; RV32I-LABEL: bset_trailing_ones_i32_mask:
750 ; RV32I:       # %bb.0:
751 ; RV32I-NEXT:    li a1, -1
752 ; RV32I-NEXT:    sll a0, a1, a0
753 ; RV32I-NEXT:    not a0, a0
754 ; RV32I-NEXT:    ret
756 ; RV32ZBS-LABEL: bset_trailing_ones_i32_mask:
757 ; RV32ZBS:       # %bb.0:
758 ; RV32ZBS-NEXT:    bset a0, zero, a0
759 ; RV32ZBS-NEXT:    addi a0, a0, -1
760 ; RV32ZBS-NEXT:    ret
761   %and = and i32 %a, 31
762   %shift = shl nsw i32 -1, %and
763   %not = xor i32 %shift, -1
764   ret i32 %not
767 define i32 @bset_trailing_ones_i32_no_mask(i32 %a) nounwind {
768 ; RV32I-LABEL: bset_trailing_ones_i32_no_mask:
769 ; RV32I:       # %bb.0:
770 ; RV32I-NEXT:    li a1, -1
771 ; RV32I-NEXT:    sll a0, a1, a0
772 ; RV32I-NEXT:    not a0, a0
773 ; RV32I-NEXT:    ret
775 ; RV32ZBS-LABEL: bset_trailing_ones_i32_no_mask:
776 ; RV32ZBS:       # %bb.0:
777 ; RV32ZBS-NEXT:    bset a0, zero, a0
778 ; RV32ZBS-NEXT:    addi a0, a0, -1
779 ; RV32ZBS-NEXT:    ret
780   %shift = shl nsw i32 -1, %a
781   %not = xor i32 %shift, -1
782   ret i32 %not
785 define i64 @bset_trailing_ones_i64_mask(i64 %a) nounwind {
786 ; CHECK-LABEL: bset_trailing_ones_i64_mask:
787 ; CHECK:       # %bb.0:
788 ; CHECK-NEXT:    li a2, -1
789 ; CHECK-NEXT:    andi a3, a0, 63
790 ; CHECK-NEXT:    addi a1, a3, -32
791 ; CHECK-NEXT:    sll a0, a2, a0
792 ; CHECK-NEXT:    bltz a1, .LBB43_2
793 ; CHECK-NEXT:  # %bb.1:
794 ; CHECK-NEXT:    sll a2, a2, a3
795 ; CHECK-NEXT:    j .LBB43_3
796 ; CHECK-NEXT:  .LBB43_2:
797 ; CHECK-NEXT:    not a2, a3
798 ; CHECK-NEXT:    lui a3, 524288
799 ; CHECK-NEXT:    addi a3, a3, -1
800 ; CHECK-NEXT:    srl a2, a3, a2
801 ; CHECK-NEXT:    or a2, a0, a2
802 ; CHECK-NEXT:  .LBB43_3:
803 ; CHECK-NEXT:    srai a1, a1, 31
804 ; CHECK-NEXT:    and a0, a1, a0
805 ; CHECK-NEXT:    not a1, a2
806 ; CHECK-NEXT:    not a0, a0
807 ; CHECK-NEXT:    ret
808   %and = and i64 %a, 63
809   %shift = shl nsw i64 -1, %and
810   %not = xor i64 %shift, -1
811   ret i64 %not
814 define i64 @bset_trailing_ones_i64_no_mask(i64 %a) nounwind {
815 ; CHECK-LABEL: bset_trailing_ones_i64_no_mask:
816 ; CHECK:       # %bb.0:
817 ; CHECK-NEXT:    li a1, -1
818 ; CHECK-NEXT:    addi a2, a0, -32
819 ; CHECK-NEXT:    sll a1, a1, a0
820 ; CHECK-NEXT:    bltz a2, .LBB44_2
821 ; CHECK-NEXT:  # %bb.1:
822 ; CHECK-NEXT:    mv a0, a1
823 ; CHECK-NEXT:    j .LBB44_3
824 ; CHECK-NEXT:  .LBB44_2:
825 ; CHECK-NEXT:    not a0, a0
826 ; CHECK-NEXT:    lui a3, 524288
827 ; CHECK-NEXT:    addi a3, a3, -1
828 ; CHECK-NEXT:    srl a0, a3, a0
829 ; CHECK-NEXT:    or a0, a1, a0
830 ; CHECK-NEXT:  .LBB44_3:
831 ; CHECK-NEXT:    srai a2, a2, 31
832 ; CHECK-NEXT:    and a2, a2, a1
833 ; CHECK-NEXT:    not a1, a0
834 ; CHECK-NEXT:    not a0, a2
835 ; CHECK-NEXT:    ret
836   %shift = shl nsw i64 -1, %a
837   %not = xor i64 %shift, -1
838   ret i64 %not
841 define i1 @icmp_eq_pow2(i32 %x) nounwind {
842 ; RV32I-LABEL: icmp_eq_pow2:
843 ; RV32I:       # %bb.0:
844 ; RV32I-NEXT:    lui a1, 8
845 ; RV32I-NEXT:    xor a0, a0, a1
846 ; RV32I-NEXT:    seqz a0, a0
847 ; RV32I-NEXT:    ret
849 ; RV32ZBS-LABEL: icmp_eq_pow2:
850 ; RV32ZBS:       # %bb.0:
851 ; RV32ZBS-NEXT:    binvi a0, a0, 15
852 ; RV32ZBS-NEXT:    seqz a0, a0
853 ; RV32ZBS-NEXT:    ret
854   %cmp = icmp eq i32 %x, 32768
855   ret i1 %cmp
858 define i1 @icmp_ne_pow2(i32 %x) nounwind {
859 ; RV32I-LABEL: icmp_ne_pow2:
860 ; RV32I:       # %bb.0:
861 ; RV32I-NEXT:    lui a1, 8
862 ; RV32I-NEXT:    xor a0, a0, a1
863 ; RV32I-NEXT:    seqz a0, a0
864 ; RV32I-NEXT:    ret
866 ; RV32ZBS-LABEL: icmp_ne_pow2:
867 ; RV32ZBS:       # %bb.0:
868 ; RV32ZBS-NEXT:    binvi a0, a0, 15
869 ; RV32ZBS-NEXT:    seqz a0, a0
870 ; RV32ZBS-NEXT:    ret
871   %cmp = icmp eq i32 %x, 32768
872   ret i1 %cmp
875 define i1 @icmp_eq_nonpow2(i32 %x) nounwind {
876 ; CHECK-LABEL: icmp_eq_nonpow2:
877 ; CHECK:       # %bb.0:
878 ; CHECK-NEXT:    lui a1, 8
879 ; CHECK-NEXT:    addi a1, a1, -1
880 ; CHECK-NEXT:    xor a0, a0, a1
881 ; CHECK-NEXT:    seqz a0, a0
882 ; CHECK-NEXT:    ret
883   %cmp = icmp eq i32 %x, 32767
884   ret i1 %cmp