xref: /llvm-project/llvm/test/CodeGen/RISCV/shl-cttz.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=riscv32 -mattr=+m < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I
4; RUN: llc -mtriple=riscv32 -mattr=+m,+zbb < %s \
5; RUN:   | FileCheck %s -check-prefix=RV32ZBB
6; RUN: llc -mtriple=riscv64 -mattr=+m < %s \
7; RUN:   | FileCheck %s -check-prefixes=RV64I
8; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb < %s \
9; RUN:   | FileCheck %s -check-prefixes=RV64ZBB
10
11define i8 @shl_cttz_i8(i8 %x, i8 %y) {
12; RV32I-LABEL: shl_cttz_i8:
13; RV32I:       # %bb.0: # %entry
14; RV32I-NEXT:    addi a2, a1, -1
15; RV32I-NEXT:    not a1, a1
16; RV32I-NEXT:    and a1, a1, a2
17; RV32I-NEXT:    srli a2, a1, 1
18; RV32I-NEXT:    andi a2, a2, 85
19; RV32I-NEXT:    sub a1, a1, a2
20; RV32I-NEXT:    andi a2, a1, 51
21; RV32I-NEXT:    srli a1, a1, 2
22; RV32I-NEXT:    andi a1, a1, 51
23; RV32I-NEXT:    add a1, a2, a1
24; RV32I-NEXT:    srli a2, a1, 4
25; RV32I-NEXT:    add a1, a1, a2
26; RV32I-NEXT:    andi a1, a1, 15
27; RV32I-NEXT:    sll a0, a0, a1
28; RV32I-NEXT:    ret
29;
30; RV32ZBB-LABEL: shl_cttz_i8:
31; RV32ZBB:       # %bb.0: # %entry
32; RV32ZBB-NEXT:    ctz a1, a1
33; RV32ZBB-NEXT:    sll a0, a0, a1
34; RV32ZBB-NEXT:    ret
35;
36; RV64I-LABEL: shl_cttz_i8:
37; RV64I:       # %bb.0: # %entry
38; RV64I-NEXT:    addi a2, a1, -1
39; RV64I-NEXT:    not a1, a1
40; RV64I-NEXT:    and a1, a1, a2
41; RV64I-NEXT:    srli a2, a1, 1
42; RV64I-NEXT:    andi a2, a2, 85
43; RV64I-NEXT:    subw a1, a1, a2
44; RV64I-NEXT:    andi a2, a1, 51
45; RV64I-NEXT:    srli a1, a1, 2
46; RV64I-NEXT:    andi a1, a1, 51
47; RV64I-NEXT:    add a1, a2, a1
48; RV64I-NEXT:    srli a2, a1, 4
49; RV64I-NEXT:    add a1, a1, a2
50; RV64I-NEXT:    andi a1, a1, 15
51; RV64I-NEXT:    sll a0, a0, a1
52; RV64I-NEXT:    ret
53;
54; RV64ZBB-LABEL: shl_cttz_i8:
55; RV64ZBB:       # %bb.0: # %entry
56; RV64ZBB-NEXT:    ctz a1, a1
57; RV64ZBB-NEXT:    sll a0, a0, a1
58; RV64ZBB-NEXT:    ret
59entry:
60  %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
61  %res = shl i8 %x, %cttz
62  ret i8 %res
63}
64
65define i8 @shl_cttz_constant_i8(i8 %y) {
66; RV32I-LABEL: shl_cttz_constant_i8:
67; RV32I:       # %bb.0: # %entry
68; RV32I-NEXT:    addi a1, a0, -1
69; RV32I-NEXT:    not a0, a0
70; RV32I-NEXT:    and a0, a0, a1
71; RV32I-NEXT:    srli a1, a0, 1
72; RV32I-NEXT:    andi a1, a1, 85
73; RV32I-NEXT:    sub a0, a0, a1
74; RV32I-NEXT:    andi a1, a0, 51
75; RV32I-NEXT:    srli a0, a0, 2
76; RV32I-NEXT:    andi a0, a0, 51
77; RV32I-NEXT:    add a0, a1, a0
78; RV32I-NEXT:    srli a1, a0, 4
79; RV32I-NEXT:    add a0, a0, a1
80; RV32I-NEXT:    andi a0, a0, 15
81; RV32I-NEXT:    li a1, 4
82; RV32I-NEXT:    sll a0, a1, a0
83; RV32I-NEXT:    ret
84;
85; RV32ZBB-LABEL: shl_cttz_constant_i8:
86; RV32ZBB:       # %bb.0: # %entry
87; RV32ZBB-NEXT:    ctz a0, a0
88; RV32ZBB-NEXT:    li a1, 4
89; RV32ZBB-NEXT:    sll a0, a1, a0
90; RV32ZBB-NEXT:    ret
91;
92; RV64I-LABEL: shl_cttz_constant_i8:
93; RV64I:       # %bb.0: # %entry
94; RV64I-NEXT:    addi a1, a0, -1
95; RV64I-NEXT:    not a0, a0
96; RV64I-NEXT:    and a0, a0, a1
97; RV64I-NEXT:    srli a1, a0, 1
98; RV64I-NEXT:    andi a1, a1, 85
99; RV64I-NEXT:    subw a0, a0, a1
100; RV64I-NEXT:    andi a1, a0, 51
101; RV64I-NEXT:    srli a0, a0, 2
102; RV64I-NEXT:    andi a0, a0, 51
103; RV64I-NEXT:    add a0, a1, a0
104; RV64I-NEXT:    srli a1, a0, 4
105; RV64I-NEXT:    add a0, a0, a1
106; RV64I-NEXT:    andi a0, a0, 15
107; RV64I-NEXT:    li a1, 4
108; RV64I-NEXT:    sll a0, a1, a0
109; RV64I-NEXT:    ret
110;
111; RV64ZBB-LABEL: shl_cttz_constant_i8:
112; RV64ZBB:       # %bb.0: # %entry
113; RV64ZBB-NEXT:    ctz a0, a0
114; RV64ZBB-NEXT:    li a1, 4
115; RV64ZBB-NEXT:    sll a0, a1, a0
116; RV64ZBB-NEXT:    ret
117entry:
118  %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
119  %res = shl i8 4, %cttz
120  ret i8 %res
121}
122
123define i16 @shl_cttz_i16(i16 %x, i16 %y) {
124; RV32I-LABEL: shl_cttz_i16:
125; RV32I:       # %bb.0: # %entry
126; RV32I-NEXT:    addi a2, a1, -1
127; RV32I-NEXT:    not a1, a1
128; RV32I-NEXT:    lui a3, 5
129; RV32I-NEXT:    and a1, a1, a2
130; RV32I-NEXT:    addi a2, a3, 1365
131; RV32I-NEXT:    srli a3, a1, 1
132; RV32I-NEXT:    and a2, a3, a2
133; RV32I-NEXT:    lui a3, 3
134; RV32I-NEXT:    addi a3, a3, 819
135; RV32I-NEXT:    sub a1, a1, a2
136; RV32I-NEXT:    and a2, a1, a3
137; RV32I-NEXT:    srli a1, a1, 2
138; RV32I-NEXT:    and a1, a1, a3
139; RV32I-NEXT:    add a1, a2, a1
140; RV32I-NEXT:    srli a2, a1, 4
141; RV32I-NEXT:    add a1, a1, a2
142; RV32I-NEXT:    andi a2, a1, 15
143; RV32I-NEXT:    slli a1, a1, 20
144; RV32I-NEXT:    srli a1, a1, 28
145; RV32I-NEXT:    add a1, a2, a1
146; RV32I-NEXT:    sll a0, a0, a1
147; RV32I-NEXT:    ret
148;
149; RV32ZBB-LABEL: shl_cttz_i16:
150; RV32ZBB:       # %bb.0: # %entry
151; RV32ZBB-NEXT:    ctz a1, a1
152; RV32ZBB-NEXT:    sll a0, a0, a1
153; RV32ZBB-NEXT:    ret
154;
155; RV64I-LABEL: shl_cttz_i16:
156; RV64I:       # %bb.0: # %entry
157; RV64I-NEXT:    addi a2, a1, -1
158; RV64I-NEXT:    not a1, a1
159; RV64I-NEXT:    lui a3, 5
160; RV64I-NEXT:    and a1, a1, a2
161; RV64I-NEXT:    addiw a2, a3, 1365
162; RV64I-NEXT:    srli a3, a1, 1
163; RV64I-NEXT:    and a2, a3, a2
164; RV64I-NEXT:    lui a3, 3
165; RV64I-NEXT:    addiw a3, a3, 819
166; RV64I-NEXT:    sub a1, a1, a2
167; RV64I-NEXT:    and a2, a1, a3
168; RV64I-NEXT:    srli a1, a1, 2
169; RV64I-NEXT:    and a1, a1, a3
170; RV64I-NEXT:    add a1, a2, a1
171; RV64I-NEXT:    srli a2, a1, 4
172; RV64I-NEXT:    add a1, a1, a2
173; RV64I-NEXT:    andi a2, a1, 15
174; RV64I-NEXT:    slli a1, a1, 52
175; RV64I-NEXT:    srli a1, a1, 60
176; RV64I-NEXT:    add a1, a2, a1
177; RV64I-NEXT:    sll a0, a0, a1
178; RV64I-NEXT:    ret
179;
180; RV64ZBB-LABEL: shl_cttz_i16:
181; RV64ZBB:       # %bb.0: # %entry
182; RV64ZBB-NEXT:    ctz a1, a1
183; RV64ZBB-NEXT:    sll a0, a0, a1
184; RV64ZBB-NEXT:    ret
185entry:
186  %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
187  %res = shl i16 %x, %cttz
188  ret i16 %res
189}
190
191define i16 @shl_cttz_constant_i16(i16 %y) {
192; RV32I-LABEL: shl_cttz_constant_i16:
193; RV32I:       # %bb.0: # %entry
194; RV32I-NEXT:    addi a1, a0, -1
195; RV32I-NEXT:    not a0, a0
196; RV32I-NEXT:    lui a2, 5
197; RV32I-NEXT:    and a0, a0, a1
198; RV32I-NEXT:    addi a1, a2, 1365
199; RV32I-NEXT:    srli a2, a0, 1
200; RV32I-NEXT:    and a1, a2, a1
201; RV32I-NEXT:    lui a2, 3
202; RV32I-NEXT:    addi a2, a2, 819
203; RV32I-NEXT:    sub a0, a0, a1
204; RV32I-NEXT:    and a1, a0, a2
205; RV32I-NEXT:    srli a0, a0, 2
206; RV32I-NEXT:    and a0, a0, a2
207; RV32I-NEXT:    add a0, a1, a0
208; RV32I-NEXT:    srli a1, a0, 4
209; RV32I-NEXT:    add a0, a0, a1
210; RV32I-NEXT:    andi a1, a0, 15
211; RV32I-NEXT:    slli a0, a0, 20
212; RV32I-NEXT:    srli a0, a0, 28
213; RV32I-NEXT:    add a0, a1, a0
214; RV32I-NEXT:    li a1, 4
215; RV32I-NEXT:    sll a0, a1, a0
216; RV32I-NEXT:    ret
217;
218; RV32ZBB-LABEL: shl_cttz_constant_i16:
219; RV32ZBB:       # %bb.0: # %entry
220; RV32ZBB-NEXT:    ctz a0, a0
221; RV32ZBB-NEXT:    li a1, 4
222; RV32ZBB-NEXT:    sll a0, a1, a0
223; RV32ZBB-NEXT:    ret
224;
225; RV64I-LABEL: shl_cttz_constant_i16:
226; RV64I:       # %bb.0: # %entry
227; RV64I-NEXT:    addi a1, a0, -1
228; RV64I-NEXT:    not a0, a0
229; RV64I-NEXT:    lui a2, 5
230; RV64I-NEXT:    and a0, a0, a1
231; RV64I-NEXT:    addiw a1, a2, 1365
232; RV64I-NEXT:    srli a2, a0, 1
233; RV64I-NEXT:    and a1, a2, a1
234; RV64I-NEXT:    lui a2, 3
235; RV64I-NEXT:    addiw a2, a2, 819
236; RV64I-NEXT:    sub a0, a0, a1
237; RV64I-NEXT:    and a1, a0, a2
238; RV64I-NEXT:    srli a0, a0, 2
239; RV64I-NEXT:    and a0, a0, a2
240; RV64I-NEXT:    add a0, a1, a0
241; RV64I-NEXT:    srli a1, a0, 4
242; RV64I-NEXT:    add a0, a0, a1
243; RV64I-NEXT:    andi a1, a0, 15
244; RV64I-NEXT:    slli a0, a0, 52
245; RV64I-NEXT:    srli a0, a0, 60
246; RV64I-NEXT:    add a0, a1, a0
247; RV64I-NEXT:    li a1, 4
248; RV64I-NEXT:    sll a0, a1, a0
249; RV64I-NEXT:    ret
250;
251; RV64ZBB-LABEL: shl_cttz_constant_i16:
252; RV64ZBB:       # %bb.0: # %entry
253; RV64ZBB-NEXT:    ctz a0, a0
254; RV64ZBB-NEXT:    li a1, 4
255; RV64ZBB-NEXT:    sll a0, a1, a0
256; RV64ZBB-NEXT:    ret
257entry:
258  %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
259  %res = shl i16 4, %cttz
260  ret i16 %res
261}
262
263define i32 @shl_cttz_i32(i32 %x, i32 %y) {
264; RV32I-LABEL: shl_cttz_i32:
265; RV32I:       # %bb.0: # %entry
266; RV32I-NEXT:    neg a2, a1
267; RV32I-NEXT:    and a1, a1, a2
268; RV32I-NEXT:    mul a0, a1, a0
269; RV32I-NEXT:    ret
270;
271; RV32ZBB-LABEL: shl_cttz_i32:
272; RV32ZBB:       # %bb.0: # %entry
273; RV32ZBB-NEXT:    ctz a1, a1
274; RV32ZBB-NEXT:    sll a0, a0, a1
275; RV32ZBB-NEXT:    ret
276;
277; RV64I-LABEL: shl_cttz_i32:
278; RV64I:       # %bb.0: # %entry
279; RV64I-NEXT:    negw a2, a1
280; RV64I-NEXT:    and a1, a1, a2
281; RV64I-NEXT:    lui a2, 30667
282; RV64I-NEXT:    addi a2, a2, 1329
283; RV64I-NEXT:    mul a1, a1, a2
284; RV64I-NEXT:    srliw a1, a1, 27
285; RV64I-NEXT:    lui a2, %hi(.LCPI4_0)
286; RV64I-NEXT:    addi a2, a2, %lo(.LCPI4_0)
287; RV64I-NEXT:    add a1, a2, a1
288; RV64I-NEXT:    lbu a1, 0(a1)
289; RV64I-NEXT:    sllw a0, a0, a1
290; RV64I-NEXT:    ret
291;
292; RV64ZBB-LABEL: shl_cttz_i32:
293; RV64ZBB:       # %bb.0: # %entry
294; RV64ZBB-NEXT:    ctzw a1, a1
295; RV64ZBB-NEXT:    sllw a0, a0, a1
296; RV64ZBB-NEXT:    ret
297entry:
298  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
299  %res = shl i32 %x, %cttz
300  ret i32 %res
301}
302
303define i32 @shl_cttz_i32_zero_is_defined(i32 %x, i32 %y) {
304; RV32I-LABEL: shl_cttz_i32_zero_is_defined:
305; RV32I:       # %bb.0: # %entry
306; RV32I-NEXT:    beqz a1, .LBB5_2
307; RV32I-NEXT:  # %bb.1: # %cond.false
308; RV32I-NEXT:    neg a2, a1
309; RV32I-NEXT:    and a1, a1, a2
310; RV32I-NEXT:    lui a2, 30667
311; RV32I-NEXT:    addi a2, a2, 1329
312; RV32I-NEXT:    mul a1, a1, a2
313; RV32I-NEXT:    srli a1, a1, 27
314; RV32I-NEXT:    lui a2, %hi(.LCPI5_0)
315; RV32I-NEXT:    addi a2, a2, %lo(.LCPI5_0)
316; RV32I-NEXT:    add a1, a2, a1
317; RV32I-NEXT:    lbu a1, 0(a1)
318; RV32I-NEXT:    sll a0, a0, a1
319; RV32I-NEXT:    ret
320; RV32I-NEXT:  .LBB5_2:
321; RV32I-NEXT:    li a1, 32
322; RV32I-NEXT:    sll a0, a0, a1
323; RV32I-NEXT:    ret
324;
325; RV32ZBB-LABEL: shl_cttz_i32_zero_is_defined:
326; RV32ZBB:       # %bb.0: # %entry
327; RV32ZBB-NEXT:    ctz a1, a1
328; RV32ZBB-NEXT:    sll a0, a0, a1
329; RV32ZBB-NEXT:    ret
330;
331; RV64I-LABEL: shl_cttz_i32_zero_is_defined:
332; RV64I:       # %bb.0: # %entry
333; RV64I-NEXT:    sext.w a2, a1
334; RV64I-NEXT:    beqz a2, .LBB5_2
335; RV64I-NEXT:  # %bb.1: # %cond.false
336; RV64I-NEXT:    negw a2, a1
337; RV64I-NEXT:    and a1, a1, a2
338; RV64I-NEXT:    lui a2, 30667
339; RV64I-NEXT:    addi a2, a2, 1329
340; RV64I-NEXT:    mul a1, a1, a2
341; RV64I-NEXT:    srliw a1, a1, 27
342; RV64I-NEXT:    lui a2, %hi(.LCPI5_0)
343; RV64I-NEXT:    addi a2, a2, %lo(.LCPI5_0)
344; RV64I-NEXT:    add a1, a2, a1
345; RV64I-NEXT:    lbu a1, 0(a1)
346; RV64I-NEXT:    sllw a0, a0, a1
347; RV64I-NEXT:    ret
348; RV64I-NEXT:  .LBB5_2:
349; RV64I-NEXT:    li a1, 32
350; RV64I-NEXT:    sllw a0, a0, a1
351; RV64I-NEXT:    ret
352;
353; RV64ZBB-LABEL: shl_cttz_i32_zero_is_defined:
354; RV64ZBB:       # %bb.0: # %entry
355; RV64ZBB-NEXT:    ctzw a1, a1
356; RV64ZBB-NEXT:    sllw a0, a0, a1
357; RV64ZBB-NEXT:    ret
358entry:
359  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
360  %res = shl i32 %x, %cttz
361  ret i32 %res
362}
363
364define i32 @shl_cttz_constant_i32(i32 %y) {
365; RV32I-LABEL: shl_cttz_constant_i32:
366; RV32I:       # %bb.0: # %entry
367; RV32I-NEXT:    neg a1, a0
368; RV32I-NEXT:    and a0, a0, a1
369; RV32I-NEXT:    slli a0, a0, 2
370; RV32I-NEXT:    ret
371;
372; RV32ZBB-LABEL: shl_cttz_constant_i32:
373; RV32ZBB:       # %bb.0: # %entry
374; RV32ZBB-NEXT:    ctz a0, a0
375; RV32ZBB-NEXT:    li a1, 4
376; RV32ZBB-NEXT:    sll a0, a1, a0
377; RV32ZBB-NEXT:    ret
378;
379; RV64I-LABEL: shl_cttz_constant_i32:
380; RV64I:       # %bb.0: # %entry
381; RV64I-NEXT:    negw a1, a0
382; RV64I-NEXT:    and a0, a0, a1
383; RV64I-NEXT:    lui a1, 30667
384; RV64I-NEXT:    addi a1, a1, 1329
385; RV64I-NEXT:    mul a0, a0, a1
386; RV64I-NEXT:    srliw a0, a0, 27
387; RV64I-NEXT:    lui a1, %hi(.LCPI6_0)
388; RV64I-NEXT:    addi a1, a1, %lo(.LCPI6_0)
389; RV64I-NEXT:    add a0, a1, a0
390; RV64I-NEXT:    lbu a0, 0(a0)
391; RV64I-NEXT:    li a1, 4
392; RV64I-NEXT:    sllw a0, a1, a0
393; RV64I-NEXT:    ret
394;
395; RV64ZBB-LABEL: shl_cttz_constant_i32:
396; RV64ZBB:       # %bb.0: # %entry
397; RV64ZBB-NEXT:    ctzw a0, a0
398; RV64ZBB-NEXT:    li a1, 4
399; RV64ZBB-NEXT:    sllw a0, a1, a0
400; RV64ZBB-NEXT:    ret
401entry:
402  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
403  %res = shl i32 4, %cttz
404  ret i32 %res
405}
406
407define i32 @shl_cttz_multiuse_i32(i32 %x, i32 %y) {
408; RV32I-LABEL: shl_cttz_multiuse_i32:
409; RV32I:       # %bb.0: # %entry
410; RV32I-NEXT:    addi sp, sp, -16
411; RV32I-NEXT:    .cfi_def_cfa_offset 16
412; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
413; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
414; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
415; RV32I-NEXT:    .cfi_offset ra, -4
416; RV32I-NEXT:    .cfi_offset s0, -8
417; RV32I-NEXT:    .cfi_offset s1, -12
418; RV32I-NEXT:    neg a2, a1
419; RV32I-NEXT:    and a1, a1, a2
420; RV32I-NEXT:    lui a2, 30667
421; RV32I-NEXT:    addi a2, a2, 1329
422; RV32I-NEXT:    mul a1, a1, a2
423; RV32I-NEXT:    srli a1, a1, 27
424; RV32I-NEXT:    lui a2, %hi(.LCPI7_0)
425; RV32I-NEXT:    addi a2, a2, %lo(.LCPI7_0)
426; RV32I-NEXT:    add a1, a2, a1
427; RV32I-NEXT:    lbu s0, 0(a1)
428; RV32I-NEXT:    mv s1, a0
429; RV32I-NEXT:    mv a0, s0
430; RV32I-NEXT:    call use32
431; RV32I-NEXT:    sll a0, s1, s0
432; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
433; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
434; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
435; RV32I-NEXT:    .cfi_restore ra
436; RV32I-NEXT:    .cfi_restore s0
437; RV32I-NEXT:    .cfi_restore s1
438; RV32I-NEXT:    addi sp, sp, 16
439; RV32I-NEXT:    .cfi_def_cfa_offset 0
440; RV32I-NEXT:    ret
441;
442; RV32ZBB-LABEL: shl_cttz_multiuse_i32:
443; RV32ZBB:       # %bb.0: # %entry
444; RV32ZBB-NEXT:    addi sp, sp, -16
445; RV32ZBB-NEXT:    .cfi_def_cfa_offset 16
446; RV32ZBB-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
447; RV32ZBB-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
448; RV32ZBB-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
449; RV32ZBB-NEXT:    .cfi_offset ra, -4
450; RV32ZBB-NEXT:    .cfi_offset s0, -8
451; RV32ZBB-NEXT:    .cfi_offset s1, -12
452; RV32ZBB-NEXT:    mv s0, a0
453; RV32ZBB-NEXT:    ctz s1, a1
454; RV32ZBB-NEXT:    mv a0, s1
455; RV32ZBB-NEXT:    call use32
456; RV32ZBB-NEXT:    sll a0, s0, s1
457; RV32ZBB-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
458; RV32ZBB-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
459; RV32ZBB-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
460; RV32ZBB-NEXT:    .cfi_restore ra
461; RV32ZBB-NEXT:    .cfi_restore s0
462; RV32ZBB-NEXT:    .cfi_restore s1
463; RV32ZBB-NEXT:    addi sp, sp, 16
464; RV32ZBB-NEXT:    .cfi_def_cfa_offset 0
465; RV32ZBB-NEXT:    ret
466;
467; RV64I-LABEL: shl_cttz_multiuse_i32:
468; RV64I:       # %bb.0: # %entry
469; RV64I-NEXT:    addi sp, sp, -32
470; RV64I-NEXT:    .cfi_def_cfa_offset 32
471; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
472; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
473; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
474; RV64I-NEXT:    .cfi_offset ra, -8
475; RV64I-NEXT:    .cfi_offset s0, -16
476; RV64I-NEXT:    .cfi_offset s1, -24
477; RV64I-NEXT:    negw a2, a1
478; RV64I-NEXT:    and a1, a1, a2
479; RV64I-NEXT:    lui a2, 30667
480; RV64I-NEXT:    addi a2, a2, 1329
481; RV64I-NEXT:    mul a1, a1, a2
482; RV64I-NEXT:    srliw a1, a1, 27
483; RV64I-NEXT:    lui a2, %hi(.LCPI7_0)
484; RV64I-NEXT:    addi a2, a2, %lo(.LCPI7_0)
485; RV64I-NEXT:    add a1, a2, a1
486; RV64I-NEXT:    lbu s0, 0(a1)
487; RV64I-NEXT:    mv s1, a0
488; RV64I-NEXT:    mv a0, s0
489; RV64I-NEXT:    call use32
490; RV64I-NEXT:    sllw a0, s1, s0
491; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
492; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
493; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
494; RV64I-NEXT:    .cfi_restore ra
495; RV64I-NEXT:    .cfi_restore s0
496; RV64I-NEXT:    .cfi_restore s1
497; RV64I-NEXT:    addi sp, sp, 32
498; RV64I-NEXT:    .cfi_def_cfa_offset 0
499; RV64I-NEXT:    ret
500;
501; RV64ZBB-LABEL: shl_cttz_multiuse_i32:
502; RV64ZBB:       # %bb.0: # %entry
503; RV64ZBB-NEXT:    addi sp, sp, -32
504; RV64ZBB-NEXT:    .cfi_def_cfa_offset 32
505; RV64ZBB-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
506; RV64ZBB-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
507; RV64ZBB-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
508; RV64ZBB-NEXT:    .cfi_offset ra, -8
509; RV64ZBB-NEXT:    .cfi_offset s0, -16
510; RV64ZBB-NEXT:    .cfi_offset s1, -24
511; RV64ZBB-NEXT:    mv s0, a0
512; RV64ZBB-NEXT:    ctzw s1, a1
513; RV64ZBB-NEXT:    mv a0, s1
514; RV64ZBB-NEXT:    call use32
515; RV64ZBB-NEXT:    sllw a0, s0, s1
516; RV64ZBB-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
517; RV64ZBB-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
518; RV64ZBB-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
519; RV64ZBB-NEXT:    .cfi_restore ra
520; RV64ZBB-NEXT:    .cfi_restore s0
521; RV64ZBB-NEXT:    .cfi_restore s1
522; RV64ZBB-NEXT:    addi sp, sp, 32
523; RV64ZBB-NEXT:    .cfi_def_cfa_offset 0
524; RV64ZBB-NEXT:    ret
525entry:
526  %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
527  call void @use32(i32 %cttz)
528  %res = shl i32 %x, %cttz
529  ret i32 %res
530}
531
532define i64 @shl_cttz_i64(i64 %x, i64 %y) {
533; RV32I-LABEL: shl_cttz_i64:
534; RV32I:       # %bb.0: # %entry
535; RV32I-NEXT:    lui a4, 30667
536; RV32I-NEXT:    addi a5, a4, 1329
537; RV32I-NEXT:    lui a4, %hi(.LCPI8_0)
538; RV32I-NEXT:    addi a4, a4, %lo(.LCPI8_0)
539; RV32I-NEXT:    bnez a2, .LBB8_2
540; RV32I-NEXT:  # %bb.1: # %entry
541; RV32I-NEXT:    neg a2, a3
542; RV32I-NEXT:    and a2, a3, a2
543; RV32I-NEXT:    mul a2, a2, a5
544; RV32I-NEXT:    srli a2, a2, 27
545; RV32I-NEXT:    add a2, a4, a2
546; RV32I-NEXT:    lbu a2, 0(a2)
547; RV32I-NEXT:    addi a4, a2, 32
548; RV32I-NEXT:    j .LBB8_3
549; RV32I-NEXT:  .LBB8_2:
550; RV32I-NEXT:    neg a3, a2
551; RV32I-NEXT:    and a2, a2, a3
552; RV32I-NEXT:    mul a2, a2, a5
553; RV32I-NEXT:    srli a2, a2, 27
554; RV32I-NEXT:    add a2, a4, a2
555; RV32I-NEXT:    lbu a4, 0(a2)
556; RV32I-NEXT:  .LBB8_3: # %entry
557; RV32I-NEXT:    addi a3, a4, -32
558; RV32I-NEXT:    sll a2, a0, a4
559; RV32I-NEXT:    bltz a3, .LBB8_5
560; RV32I-NEXT:  # %bb.4: # %entry
561; RV32I-NEXT:    mv a1, a2
562; RV32I-NEXT:    j .LBB8_6
563; RV32I-NEXT:  .LBB8_5:
564; RV32I-NEXT:    sll a1, a1, a4
565; RV32I-NEXT:    not a4, a4
566; RV32I-NEXT:    srli a0, a0, 1
567; RV32I-NEXT:    srl a0, a0, a4
568; RV32I-NEXT:    or a1, a1, a0
569; RV32I-NEXT:  .LBB8_6: # %entry
570; RV32I-NEXT:    srai a0, a3, 31
571; RV32I-NEXT:    and a0, a0, a2
572; RV32I-NEXT:    ret
573;
574; RV32ZBB-LABEL: shl_cttz_i64:
575; RV32ZBB:       # %bb.0: # %entry
576; RV32ZBB-NEXT:    bnez a2, .LBB8_2
577; RV32ZBB-NEXT:  # %bb.1: # %entry
578; RV32ZBB-NEXT:    ctz a2, a3
579; RV32ZBB-NEXT:    addi a4, a2, 32
580; RV32ZBB-NEXT:    j .LBB8_3
581; RV32ZBB-NEXT:  .LBB8_2:
582; RV32ZBB-NEXT:    ctz a4, a2
583; RV32ZBB-NEXT:  .LBB8_3: # %entry
584; RV32ZBB-NEXT:    addi a3, a4, -32
585; RV32ZBB-NEXT:    sll a2, a0, a4
586; RV32ZBB-NEXT:    bltz a3, .LBB8_5
587; RV32ZBB-NEXT:  # %bb.4: # %entry
588; RV32ZBB-NEXT:    mv a1, a2
589; RV32ZBB-NEXT:    j .LBB8_6
590; RV32ZBB-NEXT:  .LBB8_5:
591; RV32ZBB-NEXT:    sll a1, a1, a4
592; RV32ZBB-NEXT:    not a4, a4
593; RV32ZBB-NEXT:    srli a0, a0, 1
594; RV32ZBB-NEXT:    srl a0, a0, a4
595; RV32ZBB-NEXT:    or a1, a1, a0
596; RV32ZBB-NEXT:  .LBB8_6: # %entry
597; RV32ZBB-NEXT:    srai a0, a3, 31
598; RV32ZBB-NEXT:    and a0, a0, a2
599; RV32ZBB-NEXT:    ret
600;
601; RV64I-LABEL: shl_cttz_i64:
602; RV64I:       # %bb.0: # %entry
603; RV64I-NEXT:    neg a2, a1
604; RV64I-NEXT:    and a1, a1, a2
605; RV64I-NEXT:    mul a0, a1, a0
606; RV64I-NEXT:    ret
607;
608; RV64ZBB-LABEL: shl_cttz_i64:
609; RV64ZBB:       # %bb.0: # %entry
610; RV64ZBB-NEXT:    ctz a1, a1
611; RV64ZBB-NEXT:    sll a0, a0, a1
612; RV64ZBB-NEXT:    ret
613entry:
614  %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
615  %res = shl i64 %x, %cttz
616  ret i64 %res
617}
618
619define i64 @shl_cttz_constant_i64(i64 %y) {
620; RV32I-LABEL: shl_cttz_constant_i64:
621; RV32I:       # %bb.0: # %entry
622; RV32I-NEXT:    lui a2, 30667
623; RV32I-NEXT:    addi a3, a2, 1329
624; RV32I-NEXT:    lui a2, %hi(.LCPI9_0)
625; RV32I-NEXT:    addi a2, a2, %lo(.LCPI9_0)
626; RV32I-NEXT:    bnez a0, .LBB9_2
627; RV32I-NEXT:  # %bb.1: # %entry
628; RV32I-NEXT:    neg a0, a1
629; RV32I-NEXT:    and a0, a1, a0
630; RV32I-NEXT:    mul a0, a0, a3
631; RV32I-NEXT:    srli a0, a0, 27
632; RV32I-NEXT:    add a0, a2, a0
633; RV32I-NEXT:    lbu a0, 0(a0)
634; RV32I-NEXT:    addi a1, a0, 32
635; RV32I-NEXT:    j .LBB9_3
636; RV32I-NEXT:  .LBB9_2:
637; RV32I-NEXT:    neg a1, a0
638; RV32I-NEXT:    and a0, a0, a1
639; RV32I-NEXT:    mul a0, a0, a3
640; RV32I-NEXT:    srli a0, a0, 27
641; RV32I-NEXT:    add a0, a2, a0
642; RV32I-NEXT:    lbu a1, 0(a0)
643; RV32I-NEXT:  .LBB9_3: # %entry
644; RV32I-NEXT:    li a0, 4
645; RV32I-NEXT:    addi a2, a1, -32
646; RV32I-NEXT:    sll a0, a0, a1
647; RV32I-NEXT:    bltz a2, .LBB9_5
648; RV32I-NEXT:  # %bb.4: # %entry
649; RV32I-NEXT:    mv a1, a0
650; RV32I-NEXT:    j .LBB9_6
651; RV32I-NEXT:  .LBB9_5:
652; RV32I-NEXT:    not a1, a1
653; RV32I-NEXT:    li a3, 2
654; RV32I-NEXT:    srl a1, a3, a1
655; RV32I-NEXT:  .LBB9_6: # %entry
656; RV32I-NEXT:    srai a2, a2, 31
657; RV32I-NEXT:    and a0, a2, a0
658; RV32I-NEXT:    ret
659;
660; RV32ZBB-LABEL: shl_cttz_constant_i64:
661; RV32ZBB:       # %bb.0: # %entry
662; RV32ZBB-NEXT:    bnez a0, .LBB9_2
663; RV32ZBB-NEXT:  # %bb.1: # %entry
664; RV32ZBB-NEXT:    ctz a0, a1
665; RV32ZBB-NEXT:    addi a1, a0, 32
666; RV32ZBB-NEXT:    j .LBB9_3
667; RV32ZBB-NEXT:  .LBB9_2:
668; RV32ZBB-NEXT:    ctz a1, a0
669; RV32ZBB-NEXT:  .LBB9_3: # %entry
670; RV32ZBB-NEXT:    li a0, 4
671; RV32ZBB-NEXT:    addi a2, a1, -32
672; RV32ZBB-NEXT:    sll a0, a0, a1
673; RV32ZBB-NEXT:    bltz a2, .LBB9_5
674; RV32ZBB-NEXT:  # %bb.4: # %entry
675; RV32ZBB-NEXT:    mv a1, a0
676; RV32ZBB-NEXT:    j .LBB9_6
677; RV32ZBB-NEXT:  .LBB9_5:
678; RV32ZBB-NEXT:    not a1, a1
679; RV32ZBB-NEXT:    li a3, 2
680; RV32ZBB-NEXT:    srl a1, a3, a1
681; RV32ZBB-NEXT:  .LBB9_6: # %entry
682; RV32ZBB-NEXT:    srai a2, a2, 31
683; RV32ZBB-NEXT:    and a0, a2, a0
684; RV32ZBB-NEXT:    ret
685;
686; RV64I-LABEL: shl_cttz_constant_i64:
687; RV64I:       # %bb.0: # %entry
688; RV64I-NEXT:    neg a1, a0
689; RV64I-NEXT:    and a0, a0, a1
690; RV64I-NEXT:    slli a0, a0, 2
691; RV64I-NEXT:    ret
692;
693; RV64ZBB-LABEL: shl_cttz_constant_i64:
694; RV64ZBB:       # %bb.0: # %entry
695; RV64ZBB-NEXT:    ctz a0, a0
696; RV64ZBB-NEXT:    li a1, 4
697; RV64ZBB-NEXT:    sll a0, a1, a0
698; RV64ZBB-NEXT:    ret
699entry:
700  %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
701  %res = shl i64 4, %cttz
702  ret i64 %res
703}
704
705declare void @use32(i32 signext)
706