xref: /llvm-project/llvm/test/CodeGen/RISCV/rv64zbs.ll (revision 9cf8c094c77db1ed9e63322bedcf28b76e5c5a43)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64I
4; RUN: llc -mtriple=riscv64 -mattr=+zbs -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBS
6; RUN: llc -mtriple=riscv64 -mattr=+zbs,+zbb -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBS
8
9define signext i32 @bclr_i32(i32 signext %a, i32 signext %b) nounwind {
10; RV64I-LABEL: bclr_i32:
11; RV64I:       # %bb.0:
12; RV64I-NEXT:    li a2, 1
13; RV64I-NEXT:    sllw a1, a2, a1
14; RV64I-NEXT:    not a1, a1
15; RV64I-NEXT:    and a0, a1, a0
16; RV64I-NEXT:    ret
17;
18; RV64ZBS-LABEL: bclr_i32:
19; RV64ZBS:       # %bb.0:
20; RV64ZBS-NEXT:    andi a1, a1, 31
21; RV64ZBS-NEXT:    bclr a0, a0, a1
22; RV64ZBS-NEXT:    sext.w a0, a0
23; RV64ZBS-NEXT:    ret
24  %and = and i32 %b, 31
25  %shl = shl nuw i32 1, %and
26  %neg = xor i32 %shl, -1
27  %and1 = and i32 %neg, %a
28  ret i32 %and1
29}
30
31define signext i32 @bclr_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
32; RV64I-LABEL: bclr_i32_no_mask:
33; RV64I:       # %bb.0:
34; RV64I-NEXT:    li a2, 1
35; RV64I-NEXT:    sllw a1, a2, a1
36; RV64I-NEXT:    not a1, a1
37; RV64I-NEXT:    and a0, a1, a0
38; RV64I-NEXT:    ret
39;
40; RV64ZBS-LABEL: bclr_i32_no_mask:
41; RV64ZBS:       # %bb.0:
42; RV64ZBS-NEXT:    bclr a0, a0, a1
43; RV64ZBS-NEXT:    sext.w a0, a0
44; RV64ZBS-NEXT:    ret
45  %shl = shl i32 1, %b
46  %neg = xor i32 %shl, -1
47  %and1 = and i32 %neg, %a
48  ret i32 %and1
49}
50
51define signext i32 @bclr_i32_load(ptr %p, i32 signext %b) nounwind {
52; RV64I-LABEL: bclr_i32_load:
53; RV64I:       # %bb.0:
54; RV64I-NEXT:    lw a0, 0(a0)
55; RV64I-NEXT:    li a2, 1
56; RV64I-NEXT:    sllw a1, a2, a1
57; RV64I-NEXT:    not a1, a1
58; RV64I-NEXT:    and a0, a1, a0
59; RV64I-NEXT:    ret
60;
61; RV64ZBS-LABEL: bclr_i32_load:
62; RV64ZBS:       # %bb.0:
63; RV64ZBS-NEXT:    lw a0, 0(a0)
64; RV64ZBS-NEXT:    bclr a0, a0, a1
65; RV64ZBS-NEXT:    sext.w a0, a0
66; RV64ZBS-NEXT:    ret
67  %a = load i32, ptr %p
68  %shl = shl i32 1, %b
69  %neg = xor i32 %shl, -1
70  %and1 = and i32 %neg, %a
71  ret i32 %and1
72}
73
74define i64 @bclr_i64(i64 %a, i64 %b) nounwind {
75; RV64I-LABEL: bclr_i64:
76; RV64I:       # %bb.0:
77; RV64I-NEXT:    li a2, 1
78; RV64I-NEXT:    sll a1, a2, a1
79; RV64I-NEXT:    not a1, a1
80; RV64I-NEXT:    and a0, a1, a0
81; RV64I-NEXT:    ret
82;
83; RV64ZBS-LABEL: bclr_i64:
84; RV64ZBS:       # %bb.0:
85; RV64ZBS-NEXT:    bclr a0, a0, a1
86; RV64ZBS-NEXT:    ret
87  %and = and i64 %b, 63
88  %shl = shl nuw i64 1, %and
89  %neg = xor i64 %shl, -1
90  %and1 = and i64 %neg, %a
91  ret i64 %and1
92}
93
94define i64 @bclr_i64_no_mask(i64 %a, i64 %b) nounwind {
95; RV64I-LABEL: bclr_i64_no_mask:
96; RV64I:       # %bb.0:
97; RV64I-NEXT:    li a2, 1
98; RV64I-NEXT:    sll a1, a2, a1
99; RV64I-NEXT:    not a1, a1
100; RV64I-NEXT:    and a0, a1, a0
101; RV64I-NEXT:    ret
102;
103; RV64ZBS-LABEL: bclr_i64_no_mask:
104; RV64ZBS:       # %bb.0:
105; RV64ZBS-NEXT:    bclr a0, a0, a1
106; RV64ZBS-NEXT:    ret
107  %shl = shl i64 1, %b
108  %neg = xor i64 %shl, -1
109  %and1 = and i64 %neg, %a
110  ret i64 %and1
111}
112
113define signext i32 @bset_i32(i32 signext %a, i32 signext %b) nounwind {
114; RV64I-LABEL: bset_i32:
115; RV64I:       # %bb.0:
116; RV64I-NEXT:    li a2, 1
117; RV64I-NEXT:    sllw a1, a2, a1
118; RV64I-NEXT:    or a0, a1, a0
119; RV64I-NEXT:    ret
120;
121; RV64ZBS-LABEL: bset_i32:
122; RV64ZBS:       # %bb.0:
123; RV64ZBS-NEXT:    andi a1, a1, 31
124; RV64ZBS-NEXT:    bset a0, a0, a1
125; RV64ZBS-NEXT:    sext.w a0, a0
126; RV64ZBS-NEXT:    ret
127  %and = and i32 %b, 31
128  %shl = shl nuw i32 1, %and
129  %or = or i32 %shl, %a
130  ret i32 %or
131}
132
133define signext i32 @bset_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
134; RV64I-LABEL: bset_i32_no_mask:
135; RV64I:       # %bb.0:
136; RV64I-NEXT:    li a2, 1
137; RV64I-NEXT:    sllw a1, a2, a1
138; RV64I-NEXT:    or a0, a1, a0
139; RV64I-NEXT:    ret
140;
141; RV64ZBS-LABEL: bset_i32_no_mask:
142; RV64ZBS:       # %bb.0:
143; RV64ZBS-NEXT:    bset a0, a0, a1
144; RV64ZBS-NEXT:    sext.w a0, a0
145; RV64ZBS-NEXT:    ret
146  %shl = shl i32 1, %b
147  %or = or i32 %shl, %a
148  ret i32 %or
149}
150
151define signext i32 @bset_i32_load(ptr %p, i32 signext %b) nounwind {
152; RV64I-LABEL: bset_i32_load:
153; RV64I:       # %bb.0:
154; RV64I-NEXT:    lw a0, 0(a0)
155; RV64I-NEXT:    li a2, 1
156; RV64I-NEXT:    sllw a1, a2, a1
157; RV64I-NEXT:    or a0, a1, a0
158; RV64I-NEXT:    ret
159;
160; RV64ZBS-LABEL: bset_i32_load:
161; RV64ZBS:       # %bb.0:
162; RV64ZBS-NEXT:    lw a0, 0(a0)
163; RV64ZBS-NEXT:    bset a0, a0, a1
164; RV64ZBS-NEXT:    sext.w a0, a0
165; RV64ZBS-NEXT:    ret
166  %a = load i32, ptr %p
167  %shl = shl i32 1, %b
168  %or = or i32 %shl, %a
169  ret i32 %or
170}
171
172; We can use bsetw for 1 << x by setting the first source to zero.
173define signext i32 @bset_i32_zero(i32 signext %a) nounwind {
174; RV64I-LABEL: bset_i32_zero:
175; RV64I:       # %bb.0:
176; RV64I-NEXT:    li a1, 1
177; RV64I-NEXT:    sllw a0, a1, a0
178; RV64I-NEXT:    ret
179;
180; RV64ZBS-LABEL: bset_i32_zero:
181; RV64ZBS:       # %bb.0:
182; RV64ZBS-NEXT:    bset a0, zero, a0
183; RV64ZBS-NEXT:    sext.w a0, a0
184; RV64ZBS-NEXT:    ret
185  %shl = shl i32 1, %a
186  ret i32 %shl
187}
188
189define i64 @bset_i64(i64 %a, i64 %b) nounwind {
190; RV64I-LABEL: bset_i64:
191; RV64I:       # %bb.0:
192; RV64I-NEXT:    li a2, 1
193; RV64I-NEXT:    sll a1, a2, a1
194; RV64I-NEXT:    or a0, a1, a0
195; RV64I-NEXT:    ret
196;
197; RV64ZBS-LABEL: bset_i64:
198; RV64ZBS:       # %bb.0:
199; RV64ZBS-NEXT:    bset a0, a0, a1
200; RV64ZBS-NEXT:    ret
201  %conv = and i64 %b, 63
202  %shl = shl nuw i64 1, %conv
203  %or = or i64 %shl, %a
204  ret i64 %or
205}
206
207define i64 @bset_i64_no_mask(i64 %a, i64 %b) nounwind {
208; RV64I-LABEL: bset_i64_no_mask:
209; RV64I:       # %bb.0:
210; RV64I-NEXT:    li a2, 1
211; RV64I-NEXT:    sll a1, a2, a1
212; RV64I-NEXT:    or a0, a1, a0
213; RV64I-NEXT:    ret
214;
215; RV64ZBS-LABEL: bset_i64_no_mask:
216; RV64ZBS:       # %bb.0:
217; RV64ZBS-NEXT:    bset a0, a0, a1
218; RV64ZBS-NEXT:    ret
219  %shl = shl i64 1, %b
220  %or = or i64 %shl, %a
221  ret i64 %or
222}
223
224; We can use bsetw for 1 << x by setting the first source to zero.
225define signext i64 @bset_i64_zero(i64 signext %a) nounwind {
226; RV64I-LABEL: bset_i64_zero:
227; RV64I:       # %bb.0:
228; RV64I-NEXT:    li a1, 1
229; RV64I-NEXT:    sll a0, a1, a0
230; RV64I-NEXT:    ret
231;
232; RV64ZBS-LABEL: bset_i64_zero:
233; RV64ZBS:       # %bb.0:
234; RV64ZBS-NEXT:    bset a0, zero, a0
235; RV64ZBS-NEXT:    ret
236  %shl = shl i64 1, %a
237  ret i64 %shl
238}
239
240define signext i32 @binv_i32(i32 signext %a, i32 signext %b) nounwind {
241; RV64I-LABEL: binv_i32:
242; RV64I:       # %bb.0:
243; RV64I-NEXT:    li a2, 1
244; RV64I-NEXT:    sllw a1, a2, a1
245; RV64I-NEXT:    xor a0, a1, a0
246; RV64I-NEXT:    ret
247;
248; RV64ZBS-LABEL: binv_i32:
249; RV64ZBS:       # %bb.0:
250; RV64ZBS-NEXT:    andi a1, a1, 31
251; RV64ZBS-NEXT:    binv a0, a0, a1
252; RV64ZBS-NEXT:    sext.w a0, a0
253; RV64ZBS-NEXT:    ret
254  %and = and i32 %b, 31
255  %shl = shl nuw i32 1, %and
256  %xor = xor i32 %shl, %a
257  ret i32 %xor
258}
259
260define signext i32 @binv_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
261; RV64I-LABEL: binv_i32_no_mask:
262; RV64I:       # %bb.0:
263; RV64I-NEXT:    li a2, 1
264; RV64I-NEXT:    sllw a1, a2, a1
265; RV64I-NEXT:    xor a0, a1, a0
266; RV64I-NEXT:    ret
267;
268; RV64ZBS-LABEL: binv_i32_no_mask:
269; RV64ZBS:       # %bb.0:
270; RV64ZBS-NEXT:    binv a0, a0, a1
271; RV64ZBS-NEXT:    sext.w a0, a0
272; RV64ZBS-NEXT:    ret
273  %shl = shl i32 1, %b
274  %xor = xor i32 %shl, %a
275  ret i32 %xor
276}
277
278define signext i32 @binv_i32_load(ptr %p, i32 signext %b) nounwind {
279; RV64I-LABEL: binv_i32_load:
280; RV64I:       # %bb.0:
281; RV64I-NEXT:    lw a0, 0(a0)
282; RV64I-NEXT:    li a2, 1
283; RV64I-NEXT:    sllw a1, a2, a1
284; RV64I-NEXT:    xor a0, a1, a0
285; RV64I-NEXT:    ret
286;
287; RV64ZBS-LABEL: binv_i32_load:
288; RV64ZBS:       # %bb.0:
289; RV64ZBS-NEXT:    lw a0, 0(a0)
290; RV64ZBS-NEXT:    binv a0, a0, a1
291; RV64ZBS-NEXT:    sext.w a0, a0
292; RV64ZBS-NEXT:    ret
293  %a = load i32, ptr %p
294  %shl = shl i32 1, %b
295  %xor = xor i32 %shl, %a
296  ret i32 %xor
297}
298
299define i64 @binv_i64(i64 %a, i64 %b) nounwind {
300; RV64I-LABEL: binv_i64:
301; RV64I:       # %bb.0:
302; RV64I-NEXT:    li a2, 1
303; RV64I-NEXT:    sll a1, a2, a1
304; RV64I-NEXT:    xor a0, a1, a0
305; RV64I-NEXT:    ret
306;
307; RV64ZBS-LABEL: binv_i64:
308; RV64ZBS:       # %bb.0:
309; RV64ZBS-NEXT:    binv a0, a0, a1
310; RV64ZBS-NEXT:    ret
311  %conv = and i64 %b, 63
312  %shl = shl nuw i64 1, %conv
313  %xor = xor i64 %shl, %a
314  ret i64 %xor
315}
316
317define i64 @binv_i64_no_mask(i64 %a, i64 %b) nounwind {
318; RV64I-LABEL: binv_i64_no_mask:
319; RV64I:       # %bb.0:
320; RV64I-NEXT:    li a2, 1
321; RV64I-NEXT:    sll a1, a2, a1
322; RV64I-NEXT:    xor a0, a1, a0
323; RV64I-NEXT:    ret
324;
325; RV64ZBS-LABEL: binv_i64_no_mask:
326; RV64ZBS:       # %bb.0:
327; RV64ZBS-NEXT:    binv a0, a0, a1
328; RV64ZBS-NEXT:    ret
329  %shl = shl nuw i64 1, %b
330  %xor = xor i64 %shl, %a
331  ret i64 %xor
332}
333
334define signext i32 @bext_i32(i32 signext %a, i32 signext %b) nounwind {
335; RV64I-LABEL: bext_i32:
336; RV64I:       # %bb.0:
337; RV64I-NEXT:    srlw a0, a0, a1
338; RV64I-NEXT:    andi a0, a0, 1
339; RV64I-NEXT:    ret
340;
341; RV64ZBS-LABEL: bext_i32:
342; RV64ZBS:       # %bb.0:
343; RV64ZBS-NEXT:    andi a1, a1, 31
344; RV64ZBS-NEXT:    bext a0, a0, a1
345; RV64ZBS-NEXT:    ret
346  %and = and i32 %b, 31
347  %shr = lshr i32 %a, %and
348  %and1 = and i32 %shr, 1
349  ret i32 %and1
350}
351
352define signext i32 @bext_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
353; RV64I-LABEL: bext_i32_no_mask:
354; RV64I:       # %bb.0:
355; RV64I-NEXT:    srlw a0, a0, a1
356; RV64I-NEXT:    andi a0, a0, 1
357; RV64I-NEXT:    ret
358;
359; RV64ZBS-LABEL: bext_i32_no_mask:
360; RV64ZBS:       # %bb.0:
361; RV64ZBS-NEXT:    bext a0, a0, a1
362; RV64ZBS-NEXT:    ret
363  %shr = lshr i32 %a, %b
364  %and1 = and i32 %shr, 1
365  ret i32 %and1
366}
367
368; This gets previous converted to (i1 (truncate (srl X, Y)). Make sure we are
369; able to use bext.
370define void @bext_i32_trunc(i32 signext %0, i32 signext %1) {
371; RV64I-LABEL: bext_i32_trunc:
372; RV64I:       # %bb.0:
373; RV64I-NEXT:    srlw a0, a0, a1
374; RV64I-NEXT:    andi a0, a0, 1
375; RV64I-NEXT:    beqz a0, .LBB19_2
376; RV64I-NEXT:  # %bb.1:
377; RV64I-NEXT:    ret
378; RV64I-NEXT:  .LBB19_2:
379; RV64I-NEXT:    tail bar
380;
381; RV64ZBS-LABEL: bext_i32_trunc:
382; RV64ZBS:       # %bb.0:
383; RV64ZBS-NEXT:    bext a0, a0, a1
384; RV64ZBS-NEXT:    beqz a0, .LBB19_2
385; RV64ZBS-NEXT:  # %bb.1:
386; RV64ZBS-NEXT:    ret
387; RV64ZBS-NEXT:  .LBB19_2:
388; RV64ZBS-NEXT:    tail bar
389  %3 = shl i32 1, %1
390  %4 = and i32 %3, %0
391  %5 = icmp eq i32 %4, 0
392  br i1 %5, label %6, label %7
393
3946:                                                ; preds = %2
395  tail call void @bar()
396  br label %7
397
3987:                                                ; preds = %6, %2
399  ret void
400}
401
402declare void @bar()
403
404define i64 @bext_i64(i64 %a, i64 %b) nounwind {
405; RV64I-LABEL: bext_i64:
406; RV64I:       # %bb.0:
407; RV64I-NEXT:    srl a0, a0, a1
408; RV64I-NEXT:    andi a0, a0, 1
409; RV64I-NEXT:    ret
410;
411; RV64ZBS-LABEL: bext_i64:
412; RV64ZBS:       # %bb.0:
413; RV64ZBS-NEXT:    bext a0, a0, a1
414; RV64ZBS-NEXT:    ret
415  %conv = and i64 %b, 63
416  %shr = lshr i64 %a, %conv
417  %and1 = and i64 %shr, 1
418  ret i64 %and1
419}
420
421define i64 @bext_i64_no_mask(i64 %a, i64 %b) nounwind {
422; RV64I-LABEL: bext_i64_no_mask:
423; RV64I:       # %bb.0:
424; RV64I-NEXT:    srl a0, a0, a1
425; RV64I-NEXT:    andi a0, a0, 1
426; RV64I-NEXT:    ret
427;
428; RV64ZBS-LABEL: bext_i64_no_mask:
429; RV64ZBS:       # %bb.0:
430; RV64ZBS-NEXT:    bext a0, a0, a1
431; RV64ZBS-NEXT:    ret
432  %shr = lshr i64 %a, %b
433  %and1 = and i64 %shr, 1
434  ret i64 %and1
435}
436
437define signext i32 @bexti_i32(i32 signext %a) nounwind {
438; RV64I-LABEL: bexti_i32:
439; RV64I:       # %bb.0:
440; RV64I-NEXT:    slli a0, a0, 58
441; RV64I-NEXT:    srli a0, a0, 63
442; RV64I-NEXT:    ret
443;
444; RV64ZBS-LABEL: bexti_i32:
445; RV64ZBS:       # %bb.0:
446; RV64ZBS-NEXT:    bexti a0, a0, 5
447; RV64ZBS-NEXT:    ret
448  %shr = lshr i32 %a, 5
449  %and = and i32 %shr, 1
450  ret i32 %and
451}
452
453define i64 @bexti_i64(i64 %a) nounwind {
454; RV64I-LABEL: bexti_i64:
455; RV64I:       # %bb.0:
456; RV64I-NEXT:    slli a0, a0, 58
457; RV64I-NEXT:    srli a0, a0, 63
458; RV64I-NEXT:    ret
459;
460; RV64ZBS-LABEL: bexti_i64:
461; RV64ZBS:       # %bb.0:
462; RV64ZBS-NEXT:    bexti a0, a0, 5
463; RV64ZBS-NEXT:    ret
464  %shr = lshr i64 %a, 5
465  %and = and i64 %shr, 1
466  ret i64 %and
467}
468
469define signext i32 @bexti_i32_cmp(i32 signext %a) nounwind {
470; RV64I-LABEL: bexti_i32_cmp:
471; RV64I:       # %bb.0:
472; RV64I-NEXT:    slli a0, a0, 58
473; RV64I-NEXT:    srli a0, a0, 63
474; RV64I-NEXT:    ret
475;
476; RV64ZBS-LABEL: bexti_i32_cmp:
477; RV64ZBS:       # %bb.0:
478; RV64ZBS-NEXT:    bexti a0, a0, 5
479; RV64ZBS-NEXT:    ret
480  %and = and i32 %a, 32
481  %cmp = icmp ne i32 %and, 0
482  %zext = zext i1 %cmp to i32
483  ret i32 %zext
484}
485
486define i64 @bexti_i64_cmp(i64 %a) nounwind {
487; RV64I-LABEL: bexti_i64_cmp:
488; RV64I:       # %bb.0:
489; RV64I-NEXT:    slli a0, a0, 58
490; RV64I-NEXT:    srli a0, a0, 63
491; RV64I-NEXT:    ret
492;
493; RV64ZBS-LABEL: bexti_i64_cmp:
494; RV64ZBS:       # %bb.0:
495; RV64ZBS-NEXT:    bexti a0, a0, 5
496; RV64ZBS-NEXT:    ret
497  %and = and i64 %a, 32
498  %cmp = icmp ne i64 %and, 0
499  %zext = zext i1 %cmp to i64
500  ret i64 %zext
501}
502
503define signext i32 @bclri_i32_10(i32 signext %a) nounwind {
504; CHECK-LABEL: bclri_i32_10:
505; CHECK:       # %bb.0:
506; CHECK-NEXT:    andi a0, a0, -1025
507; CHECK-NEXT:    ret
508  %and = and i32 %a, -1025
509  ret i32 %and
510}
511
512define signext i32 @bclri_i32_11(i32 signext %a) nounwind {
513; RV64I-LABEL: bclri_i32_11:
514; RV64I:       # %bb.0:
515; RV64I-NEXT:    lui a1, 1048575
516; RV64I-NEXT:    addiw a1, a1, 2047
517; RV64I-NEXT:    and a0, a0, a1
518; RV64I-NEXT:    ret
519;
520; RV64ZBS-LABEL: bclri_i32_11:
521; RV64ZBS:       # %bb.0:
522; RV64ZBS-NEXT:    bclri a0, a0, 11
523; RV64ZBS-NEXT:    ret
524  %and = and i32 %a, -2049
525  ret i32 %and
526}
527
528define signext i32 @bclri_i32_30(i32 signext %a) nounwind {
529; RV64I-LABEL: bclri_i32_30:
530; RV64I:       # %bb.0:
531; RV64I-NEXT:    lui a1, 786432
532; RV64I-NEXT:    addiw a1, a1, -1
533; RV64I-NEXT:    and a0, a0, a1
534; RV64I-NEXT:    ret
535;
536; RV64ZBS-LABEL: bclri_i32_30:
537; RV64ZBS:       # %bb.0:
538; RV64ZBS-NEXT:    bclri a0, a0, 30
539; RV64ZBS-NEXT:    ret
540  %and = and i32 %a, -1073741825
541  ret i32 %and
542}
543
544define signext i32 @bclri_i32_31(i32 signext %a) nounwind {
545; CHECK-LABEL: bclri_i32_31:
546; CHECK:       # %bb.0:
547; CHECK-NEXT:    slli a0, a0, 33
548; CHECK-NEXT:    srli a0, a0, 33
549; CHECK-NEXT:    ret
550  %and = and i32 %a, -2147483649
551  ret i32 %and
552}
553
554define i64 @bclri_i64_10(i64 %a) nounwind {
555; CHECK-LABEL: bclri_i64_10:
556; CHECK:       # %bb.0:
557; CHECK-NEXT:    andi a0, a0, -1025
558; CHECK-NEXT:    ret
559  %and = and i64 %a, -1025
560  ret i64 %and
561}
562
563define i64 @bclri_i64_11(i64 %a) nounwind {
564; RV64I-LABEL: bclri_i64_11:
565; RV64I:       # %bb.0:
566; RV64I-NEXT:    lui a1, 1048575
567; RV64I-NEXT:    addiw a1, a1, 2047
568; RV64I-NEXT:    and a0, a0, a1
569; RV64I-NEXT:    ret
570;
571; RV64ZBS-LABEL: bclri_i64_11:
572; RV64ZBS:       # %bb.0:
573; RV64ZBS-NEXT:    bclri a0, a0, 11
574; RV64ZBS-NEXT:    ret
575  %and = and i64 %a, -2049
576  ret i64 %and
577}
578
579define i64 @bclri_i64_30(i64 %a) nounwind {
580; RV64I-LABEL: bclri_i64_30:
581; RV64I:       # %bb.0:
582; RV64I-NEXT:    lui a1, 786432
583; RV64I-NEXT:    addiw a1, a1, -1
584; RV64I-NEXT:    and a0, a0, a1
585; RV64I-NEXT:    ret
586;
587; RV64ZBS-LABEL: bclri_i64_30:
588; RV64ZBS:       # %bb.0:
589; RV64ZBS-NEXT:    bclri a0, a0, 30
590; RV64ZBS-NEXT:    ret
591  %and = and i64 %a, -1073741825
592  ret i64 %and
593}
594
595define i64 @bclri_i64_31(i64 %a) nounwind {
596; RV64I-LABEL: bclri_i64_31:
597; RV64I:       # %bb.0:
598; RV64I-NEXT:    lui a1, 524288
599; RV64I-NEXT:    addi a1, a1, -1
600; RV64I-NEXT:    and a0, a0, a1
601; RV64I-NEXT:    ret
602;
603; RV64ZBS-LABEL: bclri_i64_31:
604; RV64ZBS:       # %bb.0:
605; RV64ZBS-NEXT:    bclri a0, a0, 31
606; RV64ZBS-NEXT:    ret
607  %and = and i64 %a, -2147483649
608  ret i64 %and
609}
610
611define i64 @bclri_i64_62(i64 %a) nounwind {
612; RV64I-LABEL: bclri_i64_62:
613; RV64I:       # %bb.0:
614; RV64I-NEXT:    li a1, -1
615; RV64I-NEXT:    slli a1, a1, 62
616; RV64I-NEXT:    addi a1, a1, -1
617; RV64I-NEXT:    and a0, a0, a1
618; RV64I-NEXT:    ret
619;
620; RV64ZBS-LABEL: bclri_i64_62:
621; RV64ZBS:       # %bb.0:
622; RV64ZBS-NEXT:    bclri a0, a0, 62
623; RV64ZBS-NEXT:    ret
624  %and = and i64 %a, -4611686018427387905
625  ret i64 %and
626}
627
628define i64 @bclri_i64_63(i64 %a) nounwind {
629; RV64I-LABEL: bclri_i64_63:
630; RV64I:       # %bb.0:
631; RV64I-NEXT:    slli a0, a0, 1
632; RV64I-NEXT:    srli a0, a0, 1
633; RV64I-NEXT:    ret
634;
635; RV64ZBS-LABEL: bclri_i64_63:
636; RV64ZBS:       # %bb.0:
637; RV64ZBS-NEXT:    bclri a0, a0, 63
638; RV64ZBS-NEXT:    ret
639  %and = and i64 %a, -9223372036854775809
640  ret i64 %and
641}
642
643define i64 @bclri_i64_large0(i64 %a) nounwind {
644; RV64I-LABEL: bclri_i64_large0:
645; RV64I:       # %bb.0:
646; RV64I-NEXT:    lui a1, 1044480
647; RV64I-NEXT:    addiw a1, a1, -256
648; RV64I-NEXT:    and a0, a0, a1
649; RV64I-NEXT:    ret
650;
651; RV64ZBS-LABEL: bclri_i64_large0:
652; RV64ZBS:       # %bb.0:
653; RV64ZBS-NEXT:    andi a0, a0, -256
654; RV64ZBS-NEXT:    bclri a0, a0, 24
655; RV64ZBS-NEXT:    ret
656  %and = and i64 %a, -16777472
657  ret i64 %and
658}
659
660define i64 @bclri_i64_large1(i64 %a) nounwind {
661; RV64I-LABEL: bclri_i64_large1:
662; RV64I:       # %bb.0:
663; RV64I-NEXT:    lui a1, 1044464
664; RV64I-NEXT:    addiw a1, a1, -1
665; RV64I-NEXT:    and a0, a0, a1
666; RV64I-NEXT:    ret
667;
668; RV64ZBS-LABEL: bclri_i64_large1:
669; RV64ZBS:       # %bb.0:
670; RV64ZBS-NEXT:    bclri a0, a0, 16
671; RV64ZBS-NEXT:    bclri a0, a0, 24
672; RV64ZBS-NEXT:    ret
673  %and = and i64 %a, -16842753
674  ret i64 %and
675}
676
677define signext i32 @bseti_i32_10(i32 signext %a) nounwind {
678; CHECK-LABEL: bseti_i32_10:
679; CHECK:       # %bb.0:
680; CHECK-NEXT:    ori a0, a0, 1024
681; CHECK-NEXT:    ret
682  %or = or i32 %a, 1024
683  ret i32 %or
684}
685
686define signext i32 @bseti_i32_11(i32 signext %a) nounwind {
687; RV64I-LABEL: bseti_i32_11:
688; RV64I:       # %bb.0:
689; RV64I-NEXT:    li a1, 1
690; RV64I-NEXT:    slli a1, a1, 11
691; RV64I-NEXT:    or a0, a0, a1
692; RV64I-NEXT:    ret
693;
694; RV64ZBS-LABEL: bseti_i32_11:
695; RV64ZBS:       # %bb.0:
696; RV64ZBS-NEXT:    bseti a0, a0, 11
697; RV64ZBS-NEXT:    ret
698  %or = or i32 %a, 2048
699  ret i32 %or
700}
701
702define signext i32 @bseti_i32_30(i32 signext %a) nounwind {
703; RV64I-LABEL: bseti_i32_30:
704; RV64I:       # %bb.0:
705; RV64I-NEXT:    lui a1, 262144
706; RV64I-NEXT:    or a0, a0, a1
707; RV64I-NEXT:    ret
708;
709; RV64ZBS-LABEL: bseti_i32_30:
710; RV64ZBS:       # %bb.0:
711; RV64ZBS-NEXT:    bseti a0, a0, 30
712; RV64ZBS-NEXT:    ret
713  %or = or i32 %a, 1073741824
714  ret i32 %or
715}
716
717define signext i32 @bseti_i32_31(i32 signext %a) nounwind {
718; CHECK-LABEL: bseti_i32_31:
719; CHECK:       # %bb.0:
720; CHECK-NEXT:    lui a1, 524288
721; CHECK-NEXT:    or a0, a0, a1
722; CHECK-NEXT:    ret
723  %or = or i32 %a, 2147483648
724  ret i32 %or
725}
726
727define i64 @bseti_i64_10(i64 %a) nounwind {
728; CHECK-LABEL: bseti_i64_10:
729; CHECK:       # %bb.0:
730; CHECK-NEXT:    ori a0, a0, 1024
731; CHECK-NEXT:    ret
732  %or = or i64 %a, 1024
733  ret i64 %or
734}
735
736define i64 @bseti_i64_11(i64 %a) nounwind {
737; RV64I-LABEL: bseti_i64_11:
738; RV64I:       # %bb.0:
739; RV64I-NEXT:    li a1, 1
740; RV64I-NEXT:    slli a1, a1, 11
741; RV64I-NEXT:    or a0, a0, a1
742; RV64I-NEXT:    ret
743;
744; RV64ZBS-LABEL: bseti_i64_11:
745; RV64ZBS:       # %bb.0:
746; RV64ZBS-NEXT:    bseti a0, a0, 11
747; RV64ZBS-NEXT:    ret
748  %or = or i64 %a, 2048
749  ret i64 %or
750}
751
752define i64 @bseti_i64_30(i64 %a) nounwind {
753; RV64I-LABEL: bseti_i64_30:
754; RV64I:       # %bb.0:
755; RV64I-NEXT:    lui a1, 262144
756; RV64I-NEXT:    or a0, a0, a1
757; RV64I-NEXT:    ret
758;
759; RV64ZBS-LABEL: bseti_i64_30:
760; RV64ZBS:       # %bb.0:
761; RV64ZBS-NEXT:    bseti a0, a0, 30
762; RV64ZBS-NEXT:    ret
763  %or = or i64 %a, 1073741824
764  ret i64 %or
765}
766
767define i64 @bseti_i64_31(i64 %a) nounwind {
768; RV64I-LABEL: bseti_i64_31:
769; RV64I:       # %bb.0:
770; RV64I-NEXT:    li a1, 1
771; RV64I-NEXT:    slli a1, a1, 31
772; RV64I-NEXT:    or a0, a0, a1
773; RV64I-NEXT:    ret
774;
775; RV64ZBS-LABEL: bseti_i64_31:
776; RV64ZBS:       # %bb.0:
777; RV64ZBS-NEXT:    bseti a0, a0, 31
778; RV64ZBS-NEXT:    ret
779  %or = or i64 %a, 2147483648
780  ret i64 %or
781}
782
783define i64 @bseti_i64_62(i64 %a) nounwind {
784; RV64I-LABEL: bseti_i64_62:
785; RV64I:       # %bb.0:
786; RV64I-NEXT:    li a1, 1
787; RV64I-NEXT:    slli a1, a1, 62
788; RV64I-NEXT:    or a0, a0, a1
789; RV64I-NEXT:    ret
790;
791; RV64ZBS-LABEL: bseti_i64_62:
792; RV64ZBS:       # %bb.0:
793; RV64ZBS-NEXT:    bseti a0, a0, 62
794; RV64ZBS-NEXT:    ret
795  %or = or i64 %a, 4611686018427387904
796  ret i64 %or
797}
798
799define i64 @bseti_i64_63(i64 %a) nounwind {
800; RV64I-LABEL: bseti_i64_63:
801; RV64I:       # %bb.0:
802; RV64I-NEXT:    li a1, -1
803; RV64I-NEXT:    slli a1, a1, 63
804; RV64I-NEXT:    or a0, a0, a1
805; RV64I-NEXT:    ret
806;
807; RV64ZBS-LABEL: bseti_i64_63:
808; RV64ZBS:       # %bb.0:
809; RV64ZBS-NEXT:    bseti a0, a0, 63
810; RV64ZBS-NEXT:    ret
811  %or = or i64 %a, 9223372036854775808
812  ret i64 %or
813}
814
815define signext i32 @binvi_i32_10(i32 signext %a) nounwind {
816; CHECK-LABEL: binvi_i32_10:
817; CHECK:       # %bb.0:
818; CHECK-NEXT:    xori a0, a0, 1024
819; CHECK-NEXT:    ret
820  %xor = xor i32 %a, 1024
821  ret i32 %xor
822}
823
824define signext i32 @binvi_i32_11(i32 signext %a) nounwind {
825; RV64I-LABEL: binvi_i32_11:
826; RV64I:       # %bb.0:
827; RV64I-NEXT:    li a1, 1
828; RV64I-NEXT:    slli a1, a1, 11
829; RV64I-NEXT:    xor a0, a0, a1
830; RV64I-NEXT:    ret
831;
832; RV64ZBS-LABEL: binvi_i32_11:
833; RV64ZBS:       # %bb.0:
834; RV64ZBS-NEXT:    binvi a0, a0, 11
835; RV64ZBS-NEXT:    ret
836  %xor = xor i32 %a, 2048
837  ret i32 %xor
838}
839
840define signext i32 @binvi_i32_30(i32 signext %a) nounwind {
841; RV64I-LABEL: binvi_i32_30:
842; RV64I:       # %bb.0:
843; RV64I-NEXT:    lui a1, 262144
844; RV64I-NEXT:    xor a0, a0, a1
845; RV64I-NEXT:    ret
846;
847; RV64ZBS-LABEL: binvi_i32_30:
848; RV64ZBS:       # %bb.0:
849; RV64ZBS-NEXT:    binvi a0, a0, 30
850; RV64ZBS-NEXT:    ret
851  %xor = xor i32 %a, 1073741824
852  ret i32 %xor
853}
854
855define signext i32 @binvi_i32_31(i32 signext %a) nounwind {
856; CHECK-LABEL: binvi_i32_31:
857; CHECK:       # %bb.0:
858; CHECK-NEXT:    lui a1, 524288
859; CHECK-NEXT:    xor a0, a0, a1
860; CHECK-NEXT:    ret
861  %xor = xor i32 %a, 2147483648
862  ret i32 %xor
863}
864
865define i64 @binvi_i64_10(i64 %a) nounwind {
866; CHECK-LABEL: binvi_i64_10:
867; CHECK:       # %bb.0:
868; CHECK-NEXT:    xori a0, a0, 1024
869; CHECK-NEXT:    ret
870  %xor = xor i64 %a, 1024
871  ret i64 %xor
872}
873
874define i64 @binvi_i64_11(i64 %a) nounwind {
875; RV64I-LABEL: binvi_i64_11:
876; RV64I:       # %bb.0:
877; RV64I-NEXT:    li a1, 1
878; RV64I-NEXT:    slli a1, a1, 11
879; RV64I-NEXT:    xor a0, a0, a1
880; RV64I-NEXT:    ret
881;
882; RV64ZBS-LABEL: binvi_i64_11:
883; RV64ZBS:       # %bb.0:
884; RV64ZBS-NEXT:    binvi a0, a0, 11
885; RV64ZBS-NEXT:    ret
886  %xor = xor i64 %a, 2048
887  ret i64 %xor
888}
889
890define i64 @binvi_i64_30(i64 %a) nounwind {
891; RV64I-LABEL: binvi_i64_30:
892; RV64I:       # %bb.0:
893; RV64I-NEXT:    lui a1, 262144
894; RV64I-NEXT:    xor a0, a0, a1
895; RV64I-NEXT:    ret
896;
897; RV64ZBS-LABEL: binvi_i64_30:
898; RV64ZBS:       # %bb.0:
899; RV64ZBS-NEXT:    binvi a0, a0, 30
900; RV64ZBS-NEXT:    ret
901  %xor = xor i64 %a, 1073741824
902  ret i64 %xor
903}
904
905define i64 @binvi_i64_31(i64 %a) nounwind {
906; RV64I-LABEL: binvi_i64_31:
907; RV64I:       # %bb.0:
908; RV64I-NEXT:    li a1, 1
909; RV64I-NEXT:    slli a1, a1, 31
910; RV64I-NEXT:    xor a0, a0, a1
911; RV64I-NEXT:    ret
912;
913; RV64ZBS-LABEL: binvi_i64_31:
914; RV64ZBS:       # %bb.0:
915; RV64ZBS-NEXT:    binvi a0, a0, 31
916; RV64ZBS-NEXT:    ret
917  %xor = xor i64 %a, 2147483648
918  ret i64 %xor
919}
920
921define i64 @binvi_i64_62(i64 %a) nounwind {
922; RV64I-LABEL: binvi_i64_62:
923; RV64I:       # %bb.0:
924; RV64I-NEXT:    li a1, 1
925; RV64I-NEXT:    slli a1, a1, 62
926; RV64I-NEXT:    xor a0, a0, a1
927; RV64I-NEXT:    ret
928;
929; RV64ZBS-LABEL: binvi_i64_62:
930; RV64ZBS:       # %bb.0:
931; RV64ZBS-NEXT:    binvi a0, a0, 62
932; RV64ZBS-NEXT:    ret
933  %xor = xor i64 %a, 4611686018427387904
934  ret i64 %xor
935}
936
937define i64 @binvi_i64_63(i64 %a) nounwind {
938; RV64I-LABEL: binvi_i64_63:
939; RV64I:       # %bb.0:
940; RV64I-NEXT:    li a1, -1
941; RV64I-NEXT:    slli a1, a1, 63
942; RV64I-NEXT:    xor a0, a0, a1
943; RV64I-NEXT:    ret
944;
945; RV64ZBS-LABEL: binvi_i64_63:
946; RV64ZBS:       # %bb.0:
947; RV64ZBS-NEXT:    binvi a0, a0, 63
948; RV64ZBS-NEXT:    ret
949  %xor = xor i64 %a, 9223372036854775808
950  ret i64 %xor
951}
952
953define i64 @xor_i64_large(i64 %a) nounwind {
954; RV64I-LABEL: xor_i64_large:
955; RV64I:       # %bb.0:
956; RV64I-NEXT:    li a1, 1
957; RV64I-NEXT:    slli a1, a1, 32
958; RV64I-NEXT:    addi a1, a1, 1
959; RV64I-NEXT:    xor a0, a0, a1
960; RV64I-NEXT:    ret
961;
962; RV64ZBS-LABEL: xor_i64_large:
963; RV64ZBS:       # %bb.0:
964; RV64ZBS-NEXT:    binvi a0, a0, 0
965; RV64ZBS-NEXT:    binvi a0, a0, 32
966; RV64ZBS-NEXT:    ret
967  %xor = xor i64 %a, 4294967297
968  ret i64 %xor
969}
970
971define i64 @xor_i64_4099(i64 %a) nounwind {
972; RV64I-LABEL: xor_i64_4099:
973; RV64I:       # %bb.0:
974; RV64I-NEXT:    lui a1, 1
975; RV64I-NEXT:    addiw a1, a1, 3
976; RV64I-NEXT:    xor a0, a0, a1
977; RV64I-NEXT:    ret
978;
979; RV64ZBS-LABEL: xor_i64_4099:
980; RV64ZBS:       # %bb.0:
981; RV64ZBS-NEXT:    xori a0, a0, 3
982; RV64ZBS-NEXT:    binvi a0, a0, 12
983; RV64ZBS-NEXT:    ret
984  %xor = xor i64 %a, 4099
985  ret i64 %xor
986}
987
988define i64 @xor_i64_96(i64 %a) nounwind {
989; CHECK-LABEL: xor_i64_96:
990; CHECK:       # %bb.0:
991; CHECK-NEXT:    xori a0, a0, 96
992; CHECK-NEXT:    ret
993  %xor = xor i64 %a, 96
994  ret i64 %xor
995}
996
997define i64 @or_i64_large(i64 %a) nounwind {
998; RV64I-LABEL: or_i64_large:
999; RV64I:       # %bb.0:
1000; RV64I-NEXT:    li a1, 1
1001; RV64I-NEXT:    slli a1, a1, 32
1002; RV64I-NEXT:    addi a1, a1, 1
1003; RV64I-NEXT:    or a0, a0, a1
1004; RV64I-NEXT:    ret
1005;
1006; RV64ZBS-LABEL: or_i64_large:
1007; RV64ZBS:       # %bb.0:
1008; RV64ZBS-NEXT:    bseti a0, a0, 0
1009; RV64ZBS-NEXT:    bseti a0, a0, 32
1010; RV64ZBS-NEXT:    ret
1011  %or = or i64 %a, 4294967297
1012  ret i64 %or
1013}
1014
1015define i64 @xor_i64_66901(i64 %a) nounwind {
1016; RV64I-LABEL: xor_i64_66901:
1017; RV64I:       # %bb.0:
1018; RV64I-NEXT:    lui a1, 16
1019; RV64I-NEXT:    addiw a1, a1, 1365
1020; RV64I-NEXT:    xor a0, a0, a1
1021; RV64I-NEXT:    ret
1022;
1023; RV64ZBS-LABEL: xor_i64_66901:
1024; RV64ZBS:       # %bb.0:
1025; RV64ZBS-NEXT:    xori a0, a0, 1365
1026; RV64ZBS-NEXT:    binvi a0, a0, 16
1027; RV64ZBS-NEXT:    ret
1028  %xor = xor i64 %a, 66901
1029  ret i64 %xor
1030}
1031
1032define i64 @or_i64_4099(i64 %a) nounwind {
1033; RV64I-LABEL: or_i64_4099:
1034; RV64I:       # %bb.0:
1035; RV64I-NEXT:    lui a1, 1
1036; RV64I-NEXT:    addiw a1, a1, 3
1037; RV64I-NEXT:    or a0, a0, a1
1038; RV64I-NEXT:    ret
1039;
1040; RV64ZBS-LABEL: or_i64_4099:
1041; RV64ZBS:       # %bb.0:
1042; RV64ZBS-NEXT:    ori a0, a0, 3
1043; RV64ZBS-NEXT:    bseti a0, a0, 12
1044; RV64ZBS-NEXT:    ret
1045  %or = or i64 %a, 4099
1046  ret i64 %or
1047}
1048
1049define i64 @or_i64_96(i64 %a) nounwind {
1050; CHECK-LABEL: or_i64_96:
1051; CHECK:       # %bb.0:
1052; CHECK-NEXT:    ori a0, a0, 96
1053; CHECK-NEXT:    ret
1054  %or = or i64 %a, 96
1055  ret i64 %or
1056}
1057
1058define i64 @or_i64_66901(i64 %a) nounwind {
1059; RV64I-LABEL: or_i64_66901:
1060; RV64I:       # %bb.0:
1061; RV64I-NEXT:    lui a1, 16
1062; RV64I-NEXT:    addiw a1, a1, 1365
1063; RV64I-NEXT:    or a0, a0, a1
1064; RV64I-NEXT:    ret
1065;
1066; RV64ZBS-LABEL: or_i64_66901:
1067; RV64ZBS:       # %bb.0:
1068; RV64ZBS-NEXT:    ori a0, a0, 1365
1069; RV64ZBS-NEXT:    bseti a0, a0, 16
1070; RV64ZBS-NEXT:    ret
1071  %or = or i64 %a, 66901
1072  ret i64 %or
1073}
1074
1075define signext i32 @bset_trailing_ones_i32_mask(i32 signext %a) nounwind {
1076; RV64I-LABEL: bset_trailing_ones_i32_mask:
1077; RV64I:       # %bb.0:
1078; RV64I-NEXT:    li a1, -1
1079; RV64I-NEXT:    sllw a0, a1, a0
1080; RV64I-NEXT:    not a0, a0
1081; RV64I-NEXT:    ret
1082;
1083; RV64ZBS-LABEL: bset_trailing_ones_i32_mask:
1084; RV64ZBS:       # %bb.0:
1085; RV64ZBS-NEXT:    andi a0, a0, 31
1086; RV64ZBS-NEXT:    bset a0, zero, a0
1087; RV64ZBS-NEXT:    addi a0, a0, -1
1088; RV64ZBS-NEXT:    ret
1089  %and = and i32 %a, 31
1090  %shift = shl nsw i32 -1, %and
1091  %not = xor i32 %shift, -1
1092  ret i32 %not
1093}
1094
1095define signext i32 @bset_trailing_ones_i32_no_mask(i32 signext %a) nounwind {
1096; RV64I-LABEL: bset_trailing_ones_i32_no_mask:
1097; RV64I:       # %bb.0:
1098; RV64I-NEXT:    li a1, -1
1099; RV64I-NEXT:    sllw a0, a1, a0
1100; RV64I-NEXT:    not a0, a0
1101; RV64I-NEXT:    ret
1102;
1103; RV64ZBS-LABEL: bset_trailing_ones_i32_no_mask:
1104; RV64ZBS:       # %bb.0:
1105; RV64ZBS-NEXT:    bset a0, zero, a0
1106; RV64ZBS-NEXT:    addiw a0, a0, -1
1107; RV64ZBS-NEXT:    ret
1108  %shift = shl nsw i32 -1, %a
1109  %not = xor i32 %shift, -1
1110  ret i32 %not
1111}
1112
1113define signext i64 @bset_trailing_ones_i64_mask(i64 signext %a) nounwind {
1114; RV64I-LABEL: bset_trailing_ones_i64_mask:
1115; RV64I:       # %bb.0:
1116; RV64I-NEXT:    li a1, -1
1117; RV64I-NEXT:    sll a0, a1, a0
1118; RV64I-NEXT:    not a0, a0
1119; RV64I-NEXT:    ret
1120;
1121; RV64ZBS-LABEL: bset_trailing_ones_i64_mask:
1122; RV64ZBS:       # %bb.0:
1123; RV64ZBS-NEXT:    bset a0, zero, a0
1124; RV64ZBS-NEXT:    addi a0, a0, -1
1125; RV64ZBS-NEXT:    ret
1126  %and = and i64 %a, 63
1127  %shift = shl nsw i64 -1, %and
1128  %not = xor i64 %shift, -1
1129  ret i64 %not
1130}
1131
1132define signext i64 @bset_trailing_ones_i64_no_mask(i64 signext %a) nounwind {
1133; RV64I-LABEL: bset_trailing_ones_i64_no_mask:
1134; RV64I:       # %bb.0:
1135; RV64I-NEXT:    li a1, -1
1136; RV64I-NEXT:    sll a0, a1, a0
1137; RV64I-NEXT:    not a0, a0
1138; RV64I-NEXT:    ret
1139;
1140; RV64ZBS-LABEL: bset_trailing_ones_i64_no_mask:
1141; RV64ZBS:       # %bb.0:
1142; RV64ZBS-NEXT:    bset a0, zero, a0
1143; RV64ZBS-NEXT:    addi a0, a0, -1
1144; RV64ZBS-NEXT:    ret
1145  %shift = shl nsw i64 -1, %a
1146  %not = xor i64 %shift, -1
1147  ret i64 %not
1148}
1149
1150define i1 @icmp_eq_pow2(i32 signext %x) nounwind {
1151; RV64I-LABEL: icmp_eq_pow2:
1152; RV64I:       # %bb.0:
1153; RV64I-NEXT:    lui a1, 8
1154; RV64I-NEXT:    xor a0, a0, a1
1155; RV64I-NEXT:    seqz a0, a0
1156; RV64I-NEXT:    ret
1157;
1158; RV64ZBS-LABEL: icmp_eq_pow2:
1159; RV64ZBS:       # %bb.0:
1160; RV64ZBS-NEXT:    binvi a0, a0, 15
1161; RV64ZBS-NEXT:    seqz a0, a0
1162; RV64ZBS-NEXT:    ret
1163  %cmp = icmp eq i32 %x, 32768
1164  ret i1 %cmp
1165}
1166
1167define i1 @icmp_eq_pow2_64(i64 %x) nounwind {
1168; RV64I-LABEL: icmp_eq_pow2_64:
1169; RV64I:       # %bb.0:
1170; RV64I-NEXT:    li a1, 1
1171; RV64I-NEXT:    slli a1, a1, 40
1172; RV64I-NEXT:    xor a0, a0, a1
1173; RV64I-NEXT:    seqz a0, a0
1174; RV64I-NEXT:    ret
1175;
1176; RV64ZBS-LABEL: icmp_eq_pow2_64:
1177; RV64ZBS:       # %bb.0:
1178; RV64ZBS-NEXT:    binvi a0, a0, 40
1179; RV64ZBS-NEXT:    seqz a0, a0
1180; RV64ZBS-NEXT:    ret
1181  %cmp = icmp eq i64 %x, 1099511627776
1182  ret i1 %cmp
1183}
1184
1185define i1 @icmp_ne_pow2(i32 signext %x) nounwind {
1186; RV64I-LABEL: icmp_ne_pow2:
1187; RV64I:       # %bb.0:
1188; RV64I-NEXT:    lui a1, 8
1189; RV64I-NEXT:    xor a0, a0, a1
1190; RV64I-NEXT:    seqz a0, a0
1191; RV64I-NEXT:    ret
1192;
1193; RV64ZBS-LABEL: icmp_ne_pow2:
1194; RV64ZBS:       # %bb.0:
1195; RV64ZBS-NEXT:    binvi a0, a0, 15
1196; RV64ZBS-NEXT:    seqz a0, a0
1197; RV64ZBS-NEXT:    ret
1198  %cmp = icmp eq i32 %x, 32768
1199  ret i1 %cmp
1200}
1201
1202define i1 @icmp_eq_nonpow2(i32 signext %x) nounwind {
1203; CHECK-LABEL: icmp_eq_nonpow2:
1204; CHECK:       # %bb.0:
1205; CHECK-NEXT:    lui a1, 8
1206; CHECK-NEXT:    addiw a1, a1, -1
1207; CHECK-NEXT:    xor a0, a0, a1
1208; CHECK-NEXT:    seqz a0, a0
1209; CHECK-NEXT:    ret
1210  %cmp = icmp eq i32 %x, 32767
1211  ret i1 %cmp
1212}
1213
1214define signext i32 @fold_sextinreg_shl_to_sllw(i64 %x) nounwind {
1215; CHECK-LABEL: fold_sextinreg_shl_to_sllw:
1216; CHECK:       # %bb.0: # %entry
1217; CHECK-NEXT:    li a1, 1
1218; CHECK-NEXT:    sllw a0, a1, a0
1219; CHECK-NEXT:    ret
1220entry:
1221  %mask = and i64 %x, 31
1222  %shl = shl i64 1, %mask
1223  %trunc = trunc i64 %shl to i32
1224  ret i32 %trunc
1225}
1226
1227define signext i32 @fold_sextinreg_shl_to_sllw_large_shamt(i64 %x) nounwind {
1228; RV64I-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1229; RV64I:       # %bb.0: # %entry
1230; RV64I-NEXT:    li a1, 1
1231; RV64I-NEXT:    sll a0, a1, a0
1232; RV64I-NEXT:    sext.w a0, a0
1233; RV64I-NEXT:    ret
1234;
1235; RV64ZBS-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1236; RV64ZBS:       # %bb.0: # %entry
1237; RV64ZBS-NEXT:    bset a0, zero, a0
1238; RV64ZBS-NEXT:    sext.w a0, a0
1239; RV64ZBS-NEXT:    ret
1240entry:
1241  %mask = and i64 %x, 63
1242  %shl = shl i64 1, %mask
1243  %trunc = trunc i64 %shl to i32
1244  ret i32 %trunc
1245}
1246