xref: /llvm-project/llvm/test/CodeGen/RISCV/rv32zbs.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
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
8
9define 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
17;
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
27}
28
29define 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
37;
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
46}
47
48define 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
66;
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
83;
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
103}
104
105define 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
112;
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
121}
122
123define 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
130;
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
138}
139
140; We can use bsetw for 1 << x by setting the first source to zero.
141define 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
147;
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
154}
155
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.
160
161define 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
170;
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
184}
185
186define 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
198;
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
211}
212
213define 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
220;
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
229}
230
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.
235
236define 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
245;
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
259}
260
261define 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
267;
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
276}
277
278define 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
284;
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
292}
293
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.
298
299define 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
322}
323
324define 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
330;
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
338}
339
340define 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
347;
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
356}
357
358define 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
364;
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
373}
374
375define 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
382;
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
392}
393
394define 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
401}
402
403define 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
410;
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
417}
418
419define 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
426;
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
433}
434
435define 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
441;
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
448}
449
450define 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
457;
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
465}
466
467define 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
474;
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
482}
483
484define 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
491;
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
499}
500
501define 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
508;
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
516}
517
518define 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
525}
526
527define 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
534;
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
541}
542
543define 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
549;
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
556}
557
558define 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
564;
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
571}
572
573define 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
580}
581
582define 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
589;
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
596}
597
598define 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
604;
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
611}
612
613define 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
619;
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
626}
627
628define 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
635;
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
643}
644
645define 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
652;
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
660}
661
662define 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
669}
670
671define 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
678;
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
686}
687
688define 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
695;
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
703}
704
705define 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
712;
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
720}
721
722define 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
729}
730
731define 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
738;
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
746}
747
748define 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
755;
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
765}
766
767define 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
774;
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
783}
784
785define 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
812}
813
814define 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
839}
840
841define 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
848;
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
856}
857
858define 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
865;
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
873}
874
875define 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
885}
886