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,RV64IILLEGALI32
8 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb < %s \
9 ; RUN: | FileCheck %s -check-prefixes=RV64ZBB,RV64ZBBILLEGALI32
10 ; RUN: llc -mtriple=riscv64 -mattr=+m -riscv-experimental-rv64-legal-i32 < %s \
11 ; RUN: | FileCheck %s -check-prefixes=RV64I,RV64ILEGALI32
12 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb -riscv-experimental-rv64-legal-i32 < %s \
13 ; RUN: | FileCheck %s -check-prefixes=RV64ZBB,RV64ZBBLEGALI32
15 define i8 @shl_cttz_i8(i8 %x, i8 %y) {
16 ; RV32I-LABEL: shl_cttz_i8:
17 ; RV32I: # %bb.0: # %entry
18 ; RV32I-NEXT: addi a2, a1, -1
19 ; RV32I-NEXT: not a1, a1
20 ; RV32I-NEXT: and a1, a1, a2
21 ; RV32I-NEXT: srli a2, a1, 1
22 ; RV32I-NEXT: andi a2, a2, 85
23 ; RV32I-NEXT: sub a1, a1, a2
24 ; RV32I-NEXT: andi a2, a1, 51
25 ; RV32I-NEXT: srli a1, a1, 2
26 ; RV32I-NEXT: andi a1, a1, 51
27 ; RV32I-NEXT: add a1, a2, a1
28 ; RV32I-NEXT: srli a2, a1, 4
29 ; RV32I-NEXT: add a1, a1, a2
30 ; RV32I-NEXT: andi a1, a1, 15
31 ; RV32I-NEXT: sll a0, a0, a1
34 ; RV32ZBB-LABEL: shl_cttz_i8:
35 ; RV32ZBB: # %bb.0: # %entry
36 ; RV32ZBB-NEXT: ctz a1, a1
37 ; RV32ZBB-NEXT: sll a0, a0, a1
40 ; RV64IILLEGALI32-LABEL: shl_cttz_i8:
41 ; RV64IILLEGALI32: # %bb.0: # %entry
42 ; RV64IILLEGALI32-NEXT: addi a2, a1, -1
43 ; RV64IILLEGALI32-NEXT: not a1, a1
44 ; RV64IILLEGALI32-NEXT: and a1, a1, a2
45 ; RV64IILLEGALI32-NEXT: srli a2, a1, 1
46 ; RV64IILLEGALI32-NEXT: andi a2, a2, 85
47 ; RV64IILLEGALI32-NEXT: subw a1, a1, a2
48 ; RV64IILLEGALI32-NEXT: andi a2, a1, 51
49 ; RV64IILLEGALI32-NEXT: srli a1, a1, 2
50 ; RV64IILLEGALI32-NEXT: andi a1, a1, 51
51 ; RV64IILLEGALI32-NEXT: add a1, a2, a1
52 ; RV64IILLEGALI32-NEXT: srli a2, a1, 4
53 ; RV64IILLEGALI32-NEXT: add a1, a1, a2
54 ; RV64IILLEGALI32-NEXT: andi a1, a1, 15
55 ; RV64IILLEGALI32-NEXT: sll a0, a0, a1
56 ; RV64IILLEGALI32-NEXT: ret
58 ; RV64ZBBILLEGALI32-LABEL: shl_cttz_i8:
59 ; RV64ZBBILLEGALI32: # %bb.0: # %entry
60 ; RV64ZBBILLEGALI32-NEXT: ctz a1, a1
61 ; RV64ZBBILLEGALI32-NEXT: sll a0, a0, a1
62 ; RV64ZBBILLEGALI32-NEXT: ret
64 ; RV64ILEGALI32-LABEL: shl_cttz_i8:
65 ; RV64ILEGALI32: # %bb.0: # %entry
66 ; RV64ILEGALI32-NEXT: addi a2, a1, -1
67 ; RV64ILEGALI32-NEXT: not a1, a1
68 ; RV64ILEGALI32-NEXT: and a1, a1, a2
69 ; RV64ILEGALI32-NEXT: srliw a2, a1, 1
70 ; RV64ILEGALI32-NEXT: andi a2, a2, 85
71 ; RV64ILEGALI32-NEXT: subw a1, a1, a2
72 ; RV64ILEGALI32-NEXT: andi a2, a1, 51
73 ; RV64ILEGALI32-NEXT: srliw a1, a1, 2
74 ; RV64ILEGALI32-NEXT: andi a1, a1, 51
75 ; RV64ILEGALI32-NEXT: add a1, a2, a1
76 ; RV64ILEGALI32-NEXT: srliw a2, a1, 4
77 ; RV64ILEGALI32-NEXT: add a1, a1, a2
78 ; RV64ILEGALI32-NEXT: andi a1, a1, 15
79 ; RV64ILEGALI32-NEXT: sllw a0, a0, a1
80 ; RV64ILEGALI32-NEXT: ret
82 ; RV64ZBBLEGALI32-LABEL: shl_cttz_i8:
83 ; RV64ZBBLEGALI32: # %bb.0: # %entry
84 ; RV64ZBBLEGALI32-NEXT: ctzw a1, a1
85 ; RV64ZBBLEGALI32-NEXT: sllw a0, a0, a1
86 ; RV64ZBBLEGALI32-NEXT: ret
88 %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
89 %res = shl i8 %x, %cttz
93 define i8 @shl_cttz_constant_i8(i8 %y) {
94 ; RV32I-LABEL: shl_cttz_constant_i8:
95 ; RV32I: # %bb.0: # %entry
96 ; RV32I-NEXT: addi a1, a0, -1
97 ; RV32I-NEXT: not a0, a0
98 ; RV32I-NEXT: and a0, a0, a1
99 ; RV32I-NEXT: srli a1, a0, 1
100 ; RV32I-NEXT: andi a1, a1, 85
101 ; RV32I-NEXT: sub a0, a0, a1
102 ; RV32I-NEXT: andi a1, a0, 51
103 ; RV32I-NEXT: srli a0, a0, 2
104 ; RV32I-NEXT: andi a0, a0, 51
105 ; RV32I-NEXT: add a0, a1, a0
106 ; RV32I-NEXT: srli a1, a0, 4
107 ; RV32I-NEXT: add a0, a0, a1
108 ; RV32I-NEXT: andi a0, a0, 15
109 ; RV32I-NEXT: li a1, 4
110 ; RV32I-NEXT: sll a0, a1, a0
113 ; RV32ZBB-LABEL: shl_cttz_constant_i8:
114 ; RV32ZBB: # %bb.0: # %entry
115 ; RV32ZBB-NEXT: ctz a0, a0
116 ; RV32ZBB-NEXT: li a1, 4
117 ; RV32ZBB-NEXT: sll a0, a1, a0
120 ; RV64IILLEGALI32-LABEL: shl_cttz_constant_i8:
121 ; RV64IILLEGALI32: # %bb.0: # %entry
122 ; RV64IILLEGALI32-NEXT: addi a1, a0, -1
123 ; RV64IILLEGALI32-NEXT: not a0, a0
124 ; RV64IILLEGALI32-NEXT: and a0, a0, a1
125 ; RV64IILLEGALI32-NEXT: srli a1, a0, 1
126 ; RV64IILLEGALI32-NEXT: andi a1, a1, 85
127 ; RV64IILLEGALI32-NEXT: subw a0, a0, a1
128 ; RV64IILLEGALI32-NEXT: andi a1, a0, 51
129 ; RV64IILLEGALI32-NEXT: srli a0, a0, 2
130 ; RV64IILLEGALI32-NEXT: andi a0, a0, 51
131 ; RV64IILLEGALI32-NEXT: add a0, a1, a0
132 ; RV64IILLEGALI32-NEXT: srli a1, a0, 4
133 ; RV64IILLEGALI32-NEXT: add a0, a0, a1
134 ; RV64IILLEGALI32-NEXT: andi a0, a0, 15
135 ; RV64IILLEGALI32-NEXT: li a1, 4
136 ; RV64IILLEGALI32-NEXT: sll a0, a1, a0
137 ; RV64IILLEGALI32-NEXT: ret
139 ; RV64ZBBILLEGALI32-LABEL: shl_cttz_constant_i8:
140 ; RV64ZBBILLEGALI32: # %bb.0: # %entry
141 ; RV64ZBBILLEGALI32-NEXT: ctz a0, a0
142 ; RV64ZBBILLEGALI32-NEXT: li a1, 4
143 ; RV64ZBBILLEGALI32-NEXT: sll a0, a1, a0
144 ; RV64ZBBILLEGALI32-NEXT: ret
146 ; RV64ILEGALI32-LABEL: shl_cttz_constant_i8:
147 ; RV64ILEGALI32: # %bb.0: # %entry
148 ; RV64ILEGALI32-NEXT: addi a1, a0, -1
149 ; RV64ILEGALI32-NEXT: not a0, a0
150 ; RV64ILEGALI32-NEXT: and a0, a0, a1
151 ; RV64ILEGALI32-NEXT: srliw a1, a0, 1
152 ; RV64ILEGALI32-NEXT: andi a1, a1, 85
153 ; RV64ILEGALI32-NEXT: subw a0, a0, a1
154 ; RV64ILEGALI32-NEXT: andi a1, a0, 51
155 ; RV64ILEGALI32-NEXT: srliw a0, a0, 2
156 ; RV64ILEGALI32-NEXT: andi a0, a0, 51
157 ; RV64ILEGALI32-NEXT: add a0, a1, a0
158 ; RV64ILEGALI32-NEXT: srliw a1, a0, 4
159 ; RV64ILEGALI32-NEXT: add a0, a0, a1
160 ; RV64ILEGALI32-NEXT: andi a0, a0, 15
161 ; RV64ILEGALI32-NEXT: li a1, 4
162 ; RV64ILEGALI32-NEXT: sllw a0, a1, a0
163 ; RV64ILEGALI32-NEXT: ret
165 ; RV64ZBBLEGALI32-LABEL: shl_cttz_constant_i8:
166 ; RV64ZBBLEGALI32: # %bb.0: # %entry
167 ; RV64ZBBLEGALI32-NEXT: ctzw a0, a0
168 ; RV64ZBBLEGALI32-NEXT: li a1, 4
169 ; RV64ZBBLEGALI32-NEXT: sllw a0, a1, a0
170 ; RV64ZBBLEGALI32-NEXT: ret
172 %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)
173 %res = shl i8 4, %cttz
177 define i16 @shl_cttz_i16(i16 %x, i16 %y) {
178 ; RV32I-LABEL: shl_cttz_i16:
179 ; RV32I: # %bb.0: # %entry
180 ; RV32I-NEXT: addi a2, a1, -1
181 ; RV32I-NEXT: not a1, a1
182 ; RV32I-NEXT: and a1, a1, a2
183 ; RV32I-NEXT: srli a2, a1, 1
184 ; RV32I-NEXT: lui a3, 5
185 ; RV32I-NEXT: addi a3, a3, 1365
186 ; RV32I-NEXT: and a2, a2, a3
187 ; RV32I-NEXT: sub a1, a1, a2
188 ; RV32I-NEXT: lui a2, 3
189 ; RV32I-NEXT: addi a2, a2, 819
190 ; RV32I-NEXT: and a3, a1, a2
191 ; RV32I-NEXT: srli a1, a1, 2
192 ; RV32I-NEXT: and a1, a1, a2
193 ; RV32I-NEXT: add a1, a3, a1
194 ; RV32I-NEXT: srli a2, a1, 4
195 ; RV32I-NEXT: add a1, a1, a2
196 ; RV32I-NEXT: andi a2, a1, 15
197 ; RV32I-NEXT: slli a1, a1, 20
198 ; RV32I-NEXT: srli a1, a1, 28
199 ; RV32I-NEXT: add a1, a2, a1
200 ; RV32I-NEXT: sll a0, a0, a1
203 ; RV32ZBB-LABEL: shl_cttz_i16:
204 ; RV32ZBB: # %bb.0: # %entry
205 ; RV32ZBB-NEXT: ctz a1, a1
206 ; RV32ZBB-NEXT: sll a0, a0, a1
209 ; RV64IILLEGALI32-LABEL: shl_cttz_i16:
210 ; RV64IILLEGALI32: # %bb.0: # %entry
211 ; RV64IILLEGALI32-NEXT: addi a2, a1, -1
212 ; RV64IILLEGALI32-NEXT: not a1, a1
213 ; RV64IILLEGALI32-NEXT: and a1, a1, a2
214 ; RV64IILLEGALI32-NEXT: srli a2, a1, 1
215 ; RV64IILLEGALI32-NEXT: lui a3, 5
216 ; RV64IILLEGALI32-NEXT: addiw a3, a3, 1365
217 ; RV64IILLEGALI32-NEXT: and a2, a2, a3
218 ; RV64IILLEGALI32-NEXT: sub a1, a1, a2
219 ; RV64IILLEGALI32-NEXT: lui a2, 3
220 ; RV64IILLEGALI32-NEXT: addiw a2, a2, 819
221 ; RV64IILLEGALI32-NEXT: and a3, a1, a2
222 ; RV64IILLEGALI32-NEXT: srli a1, a1, 2
223 ; RV64IILLEGALI32-NEXT: and a1, a1, a2
224 ; RV64IILLEGALI32-NEXT: add a1, a3, a1
225 ; RV64IILLEGALI32-NEXT: srli a2, a1, 4
226 ; RV64IILLEGALI32-NEXT: add a1, a1, a2
227 ; RV64IILLEGALI32-NEXT: andi a2, a1, 15
228 ; RV64IILLEGALI32-NEXT: slli a1, a1, 52
229 ; RV64IILLEGALI32-NEXT: srli a1, a1, 60
230 ; RV64IILLEGALI32-NEXT: add a1, a2, a1
231 ; RV64IILLEGALI32-NEXT: sll a0, a0, a1
232 ; RV64IILLEGALI32-NEXT: ret
234 ; RV64ZBBILLEGALI32-LABEL: shl_cttz_i16:
235 ; RV64ZBBILLEGALI32: # %bb.0: # %entry
236 ; RV64ZBBILLEGALI32-NEXT: ctz a1, a1
237 ; RV64ZBBILLEGALI32-NEXT: sll a0, a0, a1
238 ; RV64ZBBILLEGALI32-NEXT: ret
240 ; RV64ILEGALI32-LABEL: shl_cttz_i16:
241 ; RV64ILEGALI32: # %bb.0: # %entry
242 ; RV64ILEGALI32-NEXT: addi a2, a1, -1
243 ; RV64ILEGALI32-NEXT: not a1, a1
244 ; RV64ILEGALI32-NEXT: and a1, a1, a2
245 ; RV64ILEGALI32-NEXT: srliw a2, a1, 1
246 ; RV64ILEGALI32-NEXT: lui a3, 5
247 ; RV64ILEGALI32-NEXT: addi a3, a3, 1365
248 ; RV64ILEGALI32-NEXT: and a2, a2, a3
249 ; RV64ILEGALI32-NEXT: subw a1, a1, a2
250 ; RV64ILEGALI32-NEXT: lui a2, 3
251 ; RV64ILEGALI32-NEXT: addi a2, a2, 819
252 ; RV64ILEGALI32-NEXT: and a3, a1, a2
253 ; RV64ILEGALI32-NEXT: srliw a1, a1, 2
254 ; RV64ILEGALI32-NEXT: and a1, a1, a2
255 ; RV64ILEGALI32-NEXT: add a1, a3, a1
256 ; RV64ILEGALI32-NEXT: srliw a2, a1, 4
257 ; RV64ILEGALI32-NEXT: add a1, a1, a2
258 ; RV64ILEGALI32-NEXT: andi a2, a1, 15
259 ; RV64ILEGALI32-NEXT: slli a1, a1, 52
260 ; RV64ILEGALI32-NEXT: srli a1, a1, 60
261 ; RV64ILEGALI32-NEXT: add a1, a2, a1
262 ; RV64ILEGALI32-NEXT: sllw a0, a0, a1
263 ; RV64ILEGALI32-NEXT: ret
265 ; RV64ZBBLEGALI32-LABEL: shl_cttz_i16:
266 ; RV64ZBBLEGALI32: # %bb.0: # %entry
267 ; RV64ZBBLEGALI32-NEXT: ctzw a1, a1
268 ; RV64ZBBLEGALI32-NEXT: sllw a0, a0, a1
269 ; RV64ZBBLEGALI32-NEXT: ret
271 %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
272 %res = shl i16 %x, %cttz
276 define i16 @shl_cttz_constant_i16(i16 %y) {
277 ; RV32I-LABEL: shl_cttz_constant_i16:
278 ; RV32I: # %bb.0: # %entry
279 ; RV32I-NEXT: addi a1, a0, -1
280 ; RV32I-NEXT: not a0, a0
281 ; RV32I-NEXT: and a0, a0, a1
282 ; RV32I-NEXT: srli a1, a0, 1
283 ; RV32I-NEXT: lui a2, 5
284 ; RV32I-NEXT: addi a2, a2, 1365
285 ; RV32I-NEXT: and a1, a1, a2
286 ; RV32I-NEXT: sub a0, a0, a1
287 ; RV32I-NEXT: lui a1, 3
288 ; RV32I-NEXT: addi a1, a1, 819
289 ; RV32I-NEXT: and a2, a0, a1
290 ; RV32I-NEXT: srli a0, a0, 2
291 ; RV32I-NEXT: and a0, a0, a1
292 ; RV32I-NEXT: add a0, a2, a0
293 ; RV32I-NEXT: srli a1, a0, 4
294 ; RV32I-NEXT: add a0, a0, a1
295 ; RV32I-NEXT: andi a1, a0, 15
296 ; RV32I-NEXT: slli a0, a0, 20
297 ; RV32I-NEXT: srli a0, a0, 28
298 ; RV32I-NEXT: add a0, a1, a0
299 ; RV32I-NEXT: li a1, 4
300 ; RV32I-NEXT: sll a0, a1, a0
303 ; RV32ZBB-LABEL: shl_cttz_constant_i16:
304 ; RV32ZBB: # %bb.0: # %entry
305 ; RV32ZBB-NEXT: ctz a0, a0
306 ; RV32ZBB-NEXT: li a1, 4
307 ; RV32ZBB-NEXT: sll a0, a1, a0
310 ; RV64IILLEGALI32-LABEL: shl_cttz_constant_i16:
311 ; RV64IILLEGALI32: # %bb.0: # %entry
312 ; RV64IILLEGALI32-NEXT: addi a1, a0, -1
313 ; RV64IILLEGALI32-NEXT: not a0, a0
314 ; RV64IILLEGALI32-NEXT: and a0, a0, a1
315 ; RV64IILLEGALI32-NEXT: srli a1, a0, 1
316 ; RV64IILLEGALI32-NEXT: lui a2, 5
317 ; RV64IILLEGALI32-NEXT: addiw a2, a2, 1365
318 ; RV64IILLEGALI32-NEXT: and a1, a1, a2
319 ; RV64IILLEGALI32-NEXT: sub a0, a0, a1
320 ; RV64IILLEGALI32-NEXT: lui a1, 3
321 ; RV64IILLEGALI32-NEXT: addiw a1, a1, 819
322 ; RV64IILLEGALI32-NEXT: and a2, a0, a1
323 ; RV64IILLEGALI32-NEXT: srli a0, a0, 2
324 ; RV64IILLEGALI32-NEXT: and a0, a0, a1
325 ; RV64IILLEGALI32-NEXT: add a0, a2, a0
326 ; RV64IILLEGALI32-NEXT: srli a1, a0, 4
327 ; RV64IILLEGALI32-NEXT: add a0, a0, a1
328 ; RV64IILLEGALI32-NEXT: andi a1, a0, 15
329 ; RV64IILLEGALI32-NEXT: slli a0, a0, 52
330 ; RV64IILLEGALI32-NEXT: srli a0, a0, 60
331 ; RV64IILLEGALI32-NEXT: add a0, a1, a0
332 ; RV64IILLEGALI32-NEXT: li a1, 4
333 ; RV64IILLEGALI32-NEXT: sll a0, a1, a0
334 ; RV64IILLEGALI32-NEXT: ret
336 ; RV64ZBBILLEGALI32-LABEL: shl_cttz_constant_i16:
337 ; RV64ZBBILLEGALI32: # %bb.0: # %entry
338 ; RV64ZBBILLEGALI32-NEXT: ctz a0, a0
339 ; RV64ZBBILLEGALI32-NEXT: li a1, 4
340 ; RV64ZBBILLEGALI32-NEXT: sll a0, a1, a0
341 ; RV64ZBBILLEGALI32-NEXT: ret
343 ; RV64ILEGALI32-LABEL: shl_cttz_constant_i16:
344 ; RV64ILEGALI32: # %bb.0: # %entry
345 ; RV64ILEGALI32-NEXT: addi a1, a0, -1
346 ; RV64ILEGALI32-NEXT: not a0, a0
347 ; RV64ILEGALI32-NEXT: and a0, a0, a1
348 ; RV64ILEGALI32-NEXT: srliw a1, a0, 1
349 ; RV64ILEGALI32-NEXT: lui a2, 5
350 ; RV64ILEGALI32-NEXT: addi a2, a2, 1365
351 ; RV64ILEGALI32-NEXT: and a1, a1, a2
352 ; RV64ILEGALI32-NEXT: subw a0, a0, a1
353 ; RV64ILEGALI32-NEXT: lui a1, 3
354 ; RV64ILEGALI32-NEXT: addi a1, a1, 819
355 ; RV64ILEGALI32-NEXT: and a2, a0, a1
356 ; RV64ILEGALI32-NEXT: srliw a0, a0, 2
357 ; RV64ILEGALI32-NEXT: and a0, a0, a1
358 ; RV64ILEGALI32-NEXT: add a0, a2, a0
359 ; RV64ILEGALI32-NEXT: srliw a1, a0, 4
360 ; RV64ILEGALI32-NEXT: add a0, a0, a1
361 ; RV64ILEGALI32-NEXT: andi a1, a0, 15
362 ; RV64ILEGALI32-NEXT: slli a0, a0, 52
363 ; RV64ILEGALI32-NEXT: srli a0, a0, 60
364 ; RV64ILEGALI32-NEXT: add a0, a1, a0
365 ; RV64ILEGALI32-NEXT: li a1, 4
366 ; RV64ILEGALI32-NEXT: sllw a0, a1, a0
367 ; RV64ILEGALI32-NEXT: ret
369 ; RV64ZBBLEGALI32-LABEL: shl_cttz_constant_i16:
370 ; RV64ZBBLEGALI32: # %bb.0: # %entry
371 ; RV64ZBBLEGALI32-NEXT: ctzw a0, a0
372 ; RV64ZBBLEGALI32-NEXT: li a1, 4
373 ; RV64ZBBLEGALI32-NEXT: sllw a0, a1, a0
374 ; RV64ZBBLEGALI32-NEXT: ret
376 %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)
377 %res = shl i16 4, %cttz
381 define i32 @shl_cttz_i32(i32 %x, i32 %y) {
382 ; RV32I-LABEL: shl_cttz_i32:
383 ; RV32I: # %bb.0: # %entry
384 ; RV32I-NEXT: neg a2, a1
385 ; RV32I-NEXT: and a1, a1, a2
386 ; RV32I-NEXT: mul a0, a1, a0
389 ; RV32ZBB-LABEL: shl_cttz_i32:
390 ; RV32ZBB: # %bb.0: # %entry
391 ; RV32ZBB-NEXT: ctz a1, a1
392 ; RV32ZBB-NEXT: sll a0, a0, a1
395 ; RV64I-LABEL: shl_cttz_i32:
396 ; RV64I: # %bb.0: # %entry
397 ; RV64I-NEXT: negw a2, a1
398 ; RV64I-NEXT: and a1, a1, a2
399 ; RV64I-NEXT: lui a2, 30667
400 ; RV64I-NEXT: addi a2, a2, 1329
401 ; RV64I-NEXT: mul a1, a1, a2
402 ; RV64I-NEXT: srliw a1, a1, 27
403 ; RV64I-NEXT: lui a2, %hi(.LCPI4_0)
404 ; RV64I-NEXT: addi a2, a2, %lo(.LCPI4_0)
405 ; RV64I-NEXT: add a1, a2, a1
406 ; RV64I-NEXT: lbu a1, 0(a1)
407 ; RV64I-NEXT: sllw a0, a0, a1
410 ; RV64ZBB-LABEL: shl_cttz_i32:
411 ; RV64ZBB: # %bb.0: # %entry
412 ; RV64ZBB-NEXT: ctzw a1, a1
413 ; RV64ZBB-NEXT: sllw a0, a0, a1
416 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
417 %res = shl i32 %x, %cttz
421 define i32 @shl_cttz_i32_zero_is_defined(i32 %x, i32 %y) {
422 ; RV32I-LABEL: shl_cttz_i32_zero_is_defined:
423 ; RV32I: # %bb.0: # %entry
424 ; RV32I-NEXT: beqz a1, .LBB5_2
425 ; RV32I-NEXT: # %bb.1: # %cond.false
426 ; RV32I-NEXT: neg a2, a1
427 ; RV32I-NEXT: and a1, a1, a2
428 ; RV32I-NEXT: lui a2, 30667
429 ; RV32I-NEXT: addi a2, a2, 1329
430 ; RV32I-NEXT: mul a1, a1, a2
431 ; RV32I-NEXT: srli a1, a1, 27
432 ; RV32I-NEXT: lui a2, %hi(.LCPI5_0)
433 ; RV32I-NEXT: addi a2, a2, %lo(.LCPI5_0)
434 ; RV32I-NEXT: add a1, a2, a1
435 ; RV32I-NEXT: lbu a1, 0(a1)
436 ; RV32I-NEXT: sll a0, a0, a1
438 ; RV32I-NEXT: .LBB5_2:
439 ; RV32I-NEXT: li a1, 32
440 ; RV32I-NEXT: sll a0, a0, a1
443 ; RV32ZBB-LABEL: shl_cttz_i32_zero_is_defined:
444 ; RV32ZBB: # %bb.0: # %entry
445 ; RV32ZBB-NEXT: ctz a1, a1
446 ; RV32ZBB-NEXT: sll a0, a0, a1
449 ; RV64I-LABEL: shl_cttz_i32_zero_is_defined:
450 ; RV64I: # %bb.0: # %entry
451 ; RV64I-NEXT: sext.w a2, a1
452 ; RV64I-NEXT: beqz a2, .LBB5_2
453 ; RV64I-NEXT: # %bb.1: # %cond.false
454 ; RV64I-NEXT: negw a2, a1
455 ; RV64I-NEXT: and a1, a1, a2
456 ; RV64I-NEXT: lui a2, 30667
457 ; RV64I-NEXT: addi a2, a2, 1329
458 ; RV64I-NEXT: mul a1, a1, a2
459 ; RV64I-NEXT: srliw a1, a1, 27
460 ; RV64I-NEXT: lui a2, %hi(.LCPI5_0)
461 ; RV64I-NEXT: addi a2, a2, %lo(.LCPI5_0)
462 ; RV64I-NEXT: add a1, a2, a1
463 ; RV64I-NEXT: lbu a1, 0(a1)
464 ; RV64I-NEXT: sllw a0, a0, a1
466 ; RV64I-NEXT: .LBB5_2:
467 ; RV64I-NEXT: li a1, 32
468 ; RV64I-NEXT: sllw a0, a0, a1
471 ; RV64ZBB-LABEL: shl_cttz_i32_zero_is_defined:
472 ; RV64ZBB: # %bb.0: # %entry
473 ; RV64ZBB-NEXT: ctzw a1, a1
474 ; RV64ZBB-NEXT: sllw a0, a0, a1
477 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)
478 %res = shl i32 %x, %cttz
482 define i32 @shl_cttz_constant_i32(i32 %y) {
483 ; RV32I-LABEL: shl_cttz_constant_i32:
484 ; RV32I: # %bb.0: # %entry
485 ; RV32I-NEXT: neg a1, a0
486 ; RV32I-NEXT: and a0, a0, a1
487 ; RV32I-NEXT: slli a0, a0, 2
490 ; RV32ZBB-LABEL: shl_cttz_constant_i32:
491 ; RV32ZBB: # %bb.0: # %entry
492 ; RV32ZBB-NEXT: ctz a0, a0
493 ; RV32ZBB-NEXT: li a1, 4
494 ; RV32ZBB-NEXT: sll a0, a1, a0
497 ; RV64I-LABEL: shl_cttz_constant_i32:
498 ; RV64I: # %bb.0: # %entry
499 ; RV64I-NEXT: negw a1, a0
500 ; RV64I-NEXT: and a0, a0, a1
501 ; RV64I-NEXT: lui a1, 30667
502 ; RV64I-NEXT: addi a1, a1, 1329
503 ; RV64I-NEXT: mul a0, a0, a1
504 ; RV64I-NEXT: srliw a0, a0, 27
505 ; RV64I-NEXT: lui a1, %hi(.LCPI6_0)
506 ; RV64I-NEXT: addi a1, a1, %lo(.LCPI6_0)
507 ; RV64I-NEXT: add a0, a1, a0
508 ; RV64I-NEXT: lbu a0, 0(a0)
509 ; RV64I-NEXT: li a1, 4
510 ; RV64I-NEXT: sllw a0, a1, a0
513 ; RV64ZBB-LABEL: shl_cttz_constant_i32:
514 ; RV64ZBB: # %bb.0: # %entry
515 ; RV64ZBB-NEXT: ctzw a0, a0
516 ; RV64ZBB-NEXT: li a1, 4
517 ; RV64ZBB-NEXT: sllw a0, a1, a0
520 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
521 %res = shl i32 4, %cttz
525 define i32 @shl_cttz_multiuse_i32(i32 %x, i32 %y) {
526 ; RV32I-LABEL: shl_cttz_multiuse_i32:
527 ; RV32I: # %bb.0: # %entry
528 ; RV32I-NEXT: addi sp, sp, -16
529 ; RV32I-NEXT: .cfi_def_cfa_offset 16
530 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
531 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
532 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
533 ; RV32I-NEXT: .cfi_offset ra, -4
534 ; RV32I-NEXT: .cfi_offset s0, -8
535 ; RV32I-NEXT: .cfi_offset s1, -12
536 ; RV32I-NEXT: neg a2, a1
537 ; RV32I-NEXT: and a1, a1, a2
538 ; RV32I-NEXT: lui a2, 30667
539 ; RV32I-NEXT: addi a2, a2, 1329
540 ; RV32I-NEXT: mul a1, a1, a2
541 ; RV32I-NEXT: srli a1, a1, 27
542 ; RV32I-NEXT: lui a2, %hi(.LCPI7_0)
543 ; RV32I-NEXT: addi a2, a2, %lo(.LCPI7_0)
544 ; RV32I-NEXT: add a1, a2, a1
545 ; RV32I-NEXT: lbu s0, 0(a1)
546 ; RV32I-NEXT: mv s1, a0
547 ; RV32I-NEXT: mv a0, s0
548 ; RV32I-NEXT: call use32
549 ; RV32I-NEXT: sll a0, s1, s0
550 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
551 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
552 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
553 ; RV32I-NEXT: addi sp, sp, 16
556 ; RV32ZBB-LABEL: shl_cttz_multiuse_i32:
557 ; RV32ZBB: # %bb.0: # %entry
558 ; RV32ZBB-NEXT: addi sp, sp, -16
559 ; RV32ZBB-NEXT: .cfi_def_cfa_offset 16
560 ; RV32ZBB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
561 ; RV32ZBB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
562 ; RV32ZBB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
563 ; RV32ZBB-NEXT: .cfi_offset ra, -4
564 ; RV32ZBB-NEXT: .cfi_offset s0, -8
565 ; RV32ZBB-NEXT: .cfi_offset s1, -12
566 ; RV32ZBB-NEXT: mv s0, a0
567 ; RV32ZBB-NEXT: ctz s1, a1
568 ; RV32ZBB-NEXT: mv a0, s1
569 ; RV32ZBB-NEXT: call use32
570 ; RV32ZBB-NEXT: sll a0, s0, s1
571 ; RV32ZBB-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
572 ; RV32ZBB-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
573 ; RV32ZBB-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
574 ; RV32ZBB-NEXT: addi sp, sp, 16
577 ; RV64I-LABEL: shl_cttz_multiuse_i32:
578 ; RV64I: # %bb.0: # %entry
579 ; RV64I-NEXT: addi sp, sp, -32
580 ; RV64I-NEXT: .cfi_def_cfa_offset 32
581 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
582 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
583 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
584 ; RV64I-NEXT: .cfi_offset ra, -8
585 ; RV64I-NEXT: .cfi_offset s0, -16
586 ; RV64I-NEXT: .cfi_offset s1, -24
587 ; RV64I-NEXT: negw a2, a1
588 ; RV64I-NEXT: and a1, a1, a2
589 ; RV64I-NEXT: lui a2, 30667
590 ; RV64I-NEXT: addi a2, a2, 1329
591 ; RV64I-NEXT: mul a1, a1, a2
592 ; RV64I-NEXT: srliw a1, a1, 27
593 ; RV64I-NEXT: lui a2, %hi(.LCPI7_0)
594 ; RV64I-NEXT: addi a2, a2, %lo(.LCPI7_0)
595 ; RV64I-NEXT: add a1, a2, a1
596 ; RV64I-NEXT: lbu s0, 0(a1)
597 ; RV64I-NEXT: mv s1, a0
598 ; RV64I-NEXT: mv a0, s0
599 ; RV64I-NEXT: call use32
600 ; RV64I-NEXT: sllw a0, s1, s0
601 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
602 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
603 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
604 ; RV64I-NEXT: addi sp, sp, 32
607 ; RV64ZBB-LABEL: shl_cttz_multiuse_i32:
608 ; RV64ZBB: # %bb.0: # %entry
609 ; RV64ZBB-NEXT: addi sp, sp, -32
610 ; RV64ZBB-NEXT: .cfi_def_cfa_offset 32
611 ; RV64ZBB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
612 ; RV64ZBB-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
613 ; RV64ZBB-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
614 ; RV64ZBB-NEXT: .cfi_offset ra, -8
615 ; RV64ZBB-NEXT: .cfi_offset s0, -16
616 ; RV64ZBB-NEXT: .cfi_offset s1, -24
617 ; RV64ZBB-NEXT: mv s0, a0
618 ; RV64ZBB-NEXT: ctzw s1, a1
619 ; RV64ZBB-NEXT: mv a0, s1
620 ; RV64ZBB-NEXT: call use32
621 ; RV64ZBB-NEXT: sllw a0, s0, s1
622 ; RV64ZBB-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
623 ; RV64ZBB-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
624 ; RV64ZBB-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
625 ; RV64ZBB-NEXT: addi sp, sp, 32
628 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)
629 call void @use32(i32 %cttz)
630 %res = shl i32 %x, %cttz
634 define i64 @shl_cttz_i64(i64 %x, i64 %y) {
635 ; RV32I-LABEL: shl_cttz_i64:
636 ; RV32I: # %bb.0: # %entry
637 ; RV32I-NEXT: lui a4, 30667
638 ; RV32I-NEXT: addi a5, a4, 1329
639 ; RV32I-NEXT: lui a4, %hi(.LCPI8_0)
640 ; RV32I-NEXT: addi a4, a4, %lo(.LCPI8_0)
641 ; RV32I-NEXT: bnez a2, .LBB8_2
642 ; RV32I-NEXT: # %bb.1: # %entry
643 ; RV32I-NEXT: neg a2, a3
644 ; RV32I-NEXT: and a2, a3, a2
645 ; RV32I-NEXT: mul a2, a2, a5
646 ; RV32I-NEXT: srli a2, a2, 27
647 ; RV32I-NEXT: add a2, a4, a2
648 ; RV32I-NEXT: lbu a2, 0(a2)
649 ; RV32I-NEXT: addi a4, a2, 32
650 ; RV32I-NEXT: j .LBB8_3
651 ; RV32I-NEXT: .LBB8_2:
652 ; RV32I-NEXT: neg a3, a2
653 ; RV32I-NEXT: and a2, a2, a3
654 ; RV32I-NEXT: mul a2, a2, a5
655 ; RV32I-NEXT: srli a2, a2, 27
656 ; RV32I-NEXT: add a2, a4, a2
657 ; RV32I-NEXT: lbu a4, 0(a2)
658 ; RV32I-NEXT: .LBB8_3: # %entry
659 ; RV32I-NEXT: addi a3, a4, -32
660 ; RV32I-NEXT: sll a2, a0, a4
661 ; RV32I-NEXT: bltz a3, .LBB8_5
662 ; RV32I-NEXT: # %bb.4: # %entry
663 ; RV32I-NEXT: mv a1, a2
664 ; RV32I-NEXT: j .LBB8_6
665 ; RV32I-NEXT: .LBB8_5:
666 ; RV32I-NEXT: sll a1, a1, a4
667 ; RV32I-NEXT: not a4, a4
668 ; RV32I-NEXT: srli a0, a0, 1
669 ; RV32I-NEXT: srl a0, a0, a4
670 ; RV32I-NEXT: or a1, a1, a0
671 ; RV32I-NEXT: .LBB8_6: # %entry
672 ; RV32I-NEXT: srai a0, a3, 31
673 ; RV32I-NEXT: and a0, a0, a2
676 ; RV32ZBB-LABEL: shl_cttz_i64:
677 ; RV32ZBB: # %bb.0: # %entry
678 ; RV32ZBB-NEXT: bnez a2, .LBB8_2
679 ; RV32ZBB-NEXT: # %bb.1: # %entry
680 ; RV32ZBB-NEXT: ctz a2, a3
681 ; RV32ZBB-NEXT: addi a4, a2, 32
682 ; RV32ZBB-NEXT: j .LBB8_3
683 ; RV32ZBB-NEXT: .LBB8_2:
684 ; RV32ZBB-NEXT: ctz a4, a2
685 ; RV32ZBB-NEXT: .LBB8_3: # %entry
686 ; RV32ZBB-NEXT: addi a3, a4, -32
687 ; RV32ZBB-NEXT: sll a2, a0, a4
688 ; RV32ZBB-NEXT: bltz a3, .LBB8_5
689 ; RV32ZBB-NEXT: # %bb.4: # %entry
690 ; RV32ZBB-NEXT: mv a1, a2
691 ; RV32ZBB-NEXT: j .LBB8_6
692 ; RV32ZBB-NEXT: .LBB8_5:
693 ; RV32ZBB-NEXT: sll a1, a1, a4
694 ; RV32ZBB-NEXT: not a4, a4
695 ; RV32ZBB-NEXT: srli a0, a0, 1
696 ; RV32ZBB-NEXT: srl a0, a0, a4
697 ; RV32ZBB-NEXT: or a1, a1, a0
698 ; RV32ZBB-NEXT: .LBB8_6: # %entry
699 ; RV32ZBB-NEXT: srai a0, a3, 31
700 ; RV32ZBB-NEXT: and a0, a0, a2
703 ; RV64I-LABEL: shl_cttz_i64:
704 ; RV64I: # %bb.0: # %entry
705 ; RV64I-NEXT: neg a2, a1
706 ; RV64I-NEXT: and a1, a1, a2
707 ; RV64I-NEXT: mul a0, a1, a0
710 ; RV64ZBB-LABEL: shl_cttz_i64:
711 ; RV64ZBB: # %bb.0: # %entry
712 ; RV64ZBB-NEXT: ctz a1, a1
713 ; RV64ZBB-NEXT: sll a0, a0, a1
716 %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
717 %res = shl i64 %x, %cttz
721 define i64 @shl_cttz_constant_i64(i64 %y) {
722 ; RV32I-LABEL: shl_cttz_constant_i64:
723 ; RV32I: # %bb.0: # %entry
724 ; RV32I-NEXT: lui a2, 30667
725 ; RV32I-NEXT: addi a3, a2, 1329
726 ; RV32I-NEXT: lui a2, %hi(.LCPI9_0)
727 ; RV32I-NEXT: addi a2, a2, %lo(.LCPI9_0)
728 ; RV32I-NEXT: bnez a0, .LBB9_2
729 ; RV32I-NEXT: # %bb.1: # %entry
730 ; RV32I-NEXT: neg a0, a1
731 ; RV32I-NEXT: and a0, a1, a0
732 ; RV32I-NEXT: mul a0, a0, a3
733 ; RV32I-NEXT: srli a0, a0, 27
734 ; RV32I-NEXT: add a0, a2, a0
735 ; RV32I-NEXT: lbu a0, 0(a0)
736 ; RV32I-NEXT: addi a1, a0, 32
737 ; RV32I-NEXT: j .LBB9_3
738 ; RV32I-NEXT: .LBB9_2:
739 ; RV32I-NEXT: neg a1, a0
740 ; RV32I-NEXT: and a0, a0, a1
741 ; RV32I-NEXT: mul a0, a0, a3
742 ; RV32I-NEXT: srli a0, a0, 27
743 ; RV32I-NEXT: add a0, a2, a0
744 ; RV32I-NEXT: lbu a1, 0(a0)
745 ; RV32I-NEXT: .LBB9_3: # %entry
746 ; RV32I-NEXT: li a0, 4
747 ; RV32I-NEXT: addi a2, a1, -32
748 ; RV32I-NEXT: sll a0, a0, a1
749 ; RV32I-NEXT: bltz a2, .LBB9_5
750 ; RV32I-NEXT: # %bb.4: # %entry
751 ; RV32I-NEXT: mv a1, a0
752 ; RV32I-NEXT: j .LBB9_6
753 ; RV32I-NEXT: .LBB9_5:
754 ; RV32I-NEXT: not a1, a1
755 ; RV32I-NEXT: li a3, 2
756 ; RV32I-NEXT: srl a1, a3, a1
757 ; RV32I-NEXT: .LBB9_6: # %entry
758 ; RV32I-NEXT: srai a2, a2, 31
759 ; RV32I-NEXT: and a0, a2, a0
762 ; RV32ZBB-LABEL: shl_cttz_constant_i64:
763 ; RV32ZBB: # %bb.0: # %entry
764 ; RV32ZBB-NEXT: bnez a0, .LBB9_2
765 ; RV32ZBB-NEXT: # %bb.1: # %entry
766 ; RV32ZBB-NEXT: ctz a0, a1
767 ; RV32ZBB-NEXT: addi a1, a0, 32
768 ; RV32ZBB-NEXT: j .LBB9_3
769 ; RV32ZBB-NEXT: .LBB9_2:
770 ; RV32ZBB-NEXT: ctz a1, a0
771 ; RV32ZBB-NEXT: .LBB9_3: # %entry
772 ; RV32ZBB-NEXT: li a0, 4
773 ; RV32ZBB-NEXT: addi a2, a1, -32
774 ; RV32ZBB-NEXT: sll a0, a0, a1
775 ; RV32ZBB-NEXT: bltz a2, .LBB9_5
776 ; RV32ZBB-NEXT: # %bb.4: # %entry
777 ; RV32ZBB-NEXT: mv a1, a0
778 ; RV32ZBB-NEXT: j .LBB9_6
779 ; RV32ZBB-NEXT: .LBB9_5:
780 ; RV32ZBB-NEXT: not a1, a1
781 ; RV32ZBB-NEXT: li a3, 2
782 ; RV32ZBB-NEXT: srl a1, a3, a1
783 ; RV32ZBB-NEXT: .LBB9_6: # %entry
784 ; RV32ZBB-NEXT: srai a2, a2, 31
785 ; RV32ZBB-NEXT: and a0, a2, a0
788 ; RV64I-LABEL: shl_cttz_constant_i64:
789 ; RV64I: # %bb.0: # %entry
790 ; RV64I-NEXT: neg a1, a0
791 ; RV64I-NEXT: and a0, a0, a1
792 ; RV64I-NEXT: slli a0, a0, 2
795 ; RV64ZBB-LABEL: shl_cttz_constant_i64:
796 ; RV64ZBB: # %bb.0: # %entry
797 ; RV64ZBB-NEXT: ctz a0, a0
798 ; RV64ZBB-NEXT: li a1, 4
799 ; RV64ZBB-NEXT: sll a0, a1, a0
802 %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)
803 %res = shl i64 4, %cttz
807 declare void @use32(i32 signext)