[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / CodeGen / RISCV / shl-cttz.ll
blob500673cc29196f7777db523b11622dff8988c652
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
11 define 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
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
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
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
59 entry:
60   %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
61   %res = shl i8 %x, %cttz
62   ret i8 %res
65 define 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
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
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
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
117 entry:
118   %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
119   %res = shl i8 4, %cttz
120   ret i8 %res
123 define 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
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
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
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
185 entry:
186   %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
187   %res = shl i16 %x, %cttz
188   ret i16 %res
191 define 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
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
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
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
257 entry:
258   %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
259   %res = shl i16 4, %cttz
260   ret i16 %res
263 define 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
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
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
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
297 entry:
298   %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
299   %res = shl i32 %x, %cttz
300   ret i32 %res
303 define 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
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
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
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
358 entry:
359   %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
360   %res = shl i32 %x, %cttz
361   ret i32 %res
364 define 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
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
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
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
401 entry:
402   %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
403   %res = shl i32 4, %cttz
404   ret i32 %res
407 define 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
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
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
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
525 entry:
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
532 define 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
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
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
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
613 entry:
614   %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
615   %res = shl i64 %x, %cttz
616   ret i64 %res
619 define 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
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
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
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
699 entry:
700   %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
701   %res = shl i64 4, %cttz
702   ret i64 %res
705 declare void @use32(i32 signext)