1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --mtriple=loongarch32 -mattr=+d < %s | FileCheck %s --check-prefix=LA32
3 ; RUN: llc --mtriple=loongarch64 -mattr=+d < %s | FileCheck %s --check-prefix=LA64
5 declare i8 @llvm.ctlz.i8(i8, i1)
6 declare i16 @llvm.ctlz.i16(i16, i1)
7 declare i32 @llvm.ctlz.i32(i32, i1)
8 declare i64 @llvm.ctlz.i64(i64, i1)
9 declare i8 @llvm.ctpop.i8(i8)
10 declare i16 @llvm.ctpop.i16(i16)
11 declare i32 @llvm.ctpop.i32(i32)
12 declare i64 @llvm.ctpop.i64(i64)
13 declare i8 @llvm.cttz.i8(i8, i1)
14 declare i16 @llvm.cttz.i16(i16, i1)
15 declare i32 @llvm.cttz.i32(i32, i1)
16 declare i64 @llvm.cttz.i64(i64, i1)
18 define i8 @test_ctlz_i8(i8 %a) nounwind {
19 ; LA32-LABEL: test_ctlz_i8:
21 ; LA32-NEXT: andi $a0, $a0, 255
22 ; LA32-NEXT: clz.w $a0, $a0
23 ; LA32-NEXT: addi.w $a0, $a0, -24
26 ; LA64-LABEL: test_ctlz_i8:
28 ; LA64-NEXT: andi $a0, $a0, 255
29 ; LA64-NEXT: clz.d $a0, $a0
30 ; LA64-NEXT: addi.d $a0, $a0, -56
32 %tmp = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
36 define i16 @test_ctlz_i16(i16 %a) nounwind {
37 ; LA32-LABEL: test_ctlz_i16:
39 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0
40 ; LA32-NEXT: clz.w $a0, $a0
41 ; LA32-NEXT: addi.w $a0, $a0, -16
44 ; LA64-LABEL: test_ctlz_i16:
46 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0
47 ; LA64-NEXT: clz.d $a0, $a0
48 ; LA64-NEXT: addi.d $a0, $a0, -48
50 %tmp = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
54 define i32 @test_ctlz_i32(i32 %a) nounwind {
55 ; LA32-LABEL: test_ctlz_i32:
57 ; LA32-NEXT: clz.w $a0, $a0
60 ; LA64-LABEL: test_ctlz_i32:
62 ; LA64-NEXT: clz.w $a0, $a0
64 %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
68 define i64 @test_ctlz_i64(i64 %a) nounwind {
69 ; LA32-LABEL: test_ctlz_i64:
71 ; LA32-NEXT: sltu $a2, $zero, $a1
72 ; LA32-NEXT: clz.w $a1, $a1
73 ; LA32-NEXT: maskeqz $a1, $a1, $a2
74 ; LA32-NEXT: clz.w $a0, $a0
75 ; LA32-NEXT: addi.w $a0, $a0, 32
76 ; LA32-NEXT: masknez $a0, $a0, $a2
77 ; LA32-NEXT: or $a0, $a1, $a0
78 ; LA32-NEXT: move $a1, $zero
81 ; LA64-LABEL: test_ctlz_i64:
83 ; LA64-NEXT: clz.d $a0, $a0
85 %tmp = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
89 define i8 @test_not_ctlz_i8(i8 %a) nounwind {
90 ; LA32-LABEL: test_not_ctlz_i8:
92 ; LA32-NEXT: ori $a1, $zero, 255
93 ; LA32-NEXT: andn $a0, $a1, $a0
94 ; LA32-NEXT: clz.w $a0, $a0
95 ; LA32-NEXT: addi.w $a0, $a0, -24
98 ; LA64-LABEL: test_not_ctlz_i8:
100 ; LA64-NEXT: ori $a1, $zero, 255
101 ; LA64-NEXT: andn $a0, $a1, $a0
102 ; LA64-NEXT: clz.d $a0, $a0
103 ; LA64-NEXT: addi.d $a0, $a0, -56
106 %tmp = call i8 @llvm.ctlz.i8(i8 %neg, i1 false)
110 define i16 @test_not_ctlz_i16(i16 %a) nounwind {
111 ; LA32-LABEL: test_not_ctlz_i16:
113 ; LA32-NEXT: nor $a0, $a0, $zero
114 ; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0
115 ; LA32-NEXT: clz.w $a0, $a0
116 ; LA32-NEXT: addi.w $a0, $a0, -16
119 ; LA64-LABEL: test_not_ctlz_i16:
121 ; LA64-NEXT: nor $a0, $a0, $zero
122 ; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0
123 ; LA64-NEXT: clz.d $a0, $a0
124 ; LA64-NEXT: addi.d $a0, $a0, -48
126 %neg = xor i16 %a, -1
127 %tmp = call i16 @llvm.ctlz.i16(i16 %neg, i1 false)
131 define i32 @test_not_ctlz_i32(i32 %a) nounwind {
132 ; LA32-LABEL: test_not_ctlz_i32:
134 ; LA32-NEXT: clo.w $a0, $a0
137 ; LA64-LABEL: test_not_ctlz_i32:
139 ; LA64-NEXT: clo.w $a0, $a0
141 %neg = xor i32 %a, -1
142 %tmp = call i32 @llvm.ctlz.i32(i32 %neg, i1 false)
146 define i64 @test_not_ctlz_i64(i64 %a) nounwind {
147 ; LA32-LABEL: test_not_ctlz_i64:
149 ; LA32-NEXT: nor $a2, $a1, $zero
150 ; LA32-NEXT: sltu $a2, $zero, $a2
151 ; LA32-NEXT: clo.w $a0, $a0
152 ; LA32-NEXT: addi.w $a0, $a0, 32
153 ; LA32-NEXT: masknez $a0, $a0, $a2
154 ; LA32-NEXT: clo.w $a1, $a1
155 ; LA32-NEXT: maskeqz $a1, $a1, $a2
156 ; LA32-NEXT: or $a0, $a1, $a0
157 ; LA32-NEXT: move $a1, $zero
160 ; LA64-LABEL: test_not_ctlz_i64:
162 ; LA64-NEXT: clo.d $a0, $a0
164 %neg = xor i64 %a, -1
165 %tmp = call i64 @llvm.ctlz.i64(i64 %neg, i1 false)
169 define i8 @test_ctpop_i8(i8 %a) nounwind {
170 ; LA32-LABEL: test_ctpop_i8:
172 ; LA32-NEXT: srli.w $a1, $a0, 1
173 ; LA32-NEXT: andi $a1, $a1, 85
174 ; LA32-NEXT: sub.w $a0, $a0, $a1
175 ; LA32-NEXT: andi $a1, $a0, 51
176 ; LA32-NEXT: srli.w $a0, $a0, 2
177 ; LA32-NEXT: andi $a0, $a0, 51
178 ; LA32-NEXT: add.w $a0, $a1, $a0
179 ; LA32-NEXT: srli.w $a1, $a0, 4
180 ; LA32-NEXT: add.w $a0, $a0, $a1
181 ; LA32-NEXT: andi $a0, $a0, 15
184 ; LA64-LABEL: test_ctpop_i8:
186 ; LA64-NEXT: srli.d $a1, $a0, 1
187 ; LA64-NEXT: andi $a1, $a1, 85
188 ; LA64-NEXT: sub.d $a0, $a0, $a1
189 ; LA64-NEXT: andi $a1, $a0, 51
190 ; LA64-NEXT: srli.d $a0, $a0, 2
191 ; LA64-NEXT: andi $a0, $a0, 51
192 ; LA64-NEXT: add.d $a0, $a1, $a0
193 ; LA64-NEXT: srli.d $a1, $a0, 4
194 ; LA64-NEXT: add.d $a0, $a0, $a1
195 ; LA64-NEXT: andi $a0, $a0, 15
197 %1 = call i8 @llvm.ctpop.i8(i8 %a)
201 define i16 @test_ctpop_i16(i16 %a) nounwind {
202 ; LA32-LABEL: test_ctpop_i16:
204 ; LA32-NEXT: srli.w $a1, $a0, 1
205 ; LA32-NEXT: lu12i.w $a2, 5
206 ; LA32-NEXT: ori $a2, $a2, 1365
207 ; LA32-NEXT: and $a1, $a1, $a2
208 ; LA32-NEXT: sub.w $a0, $a0, $a1
209 ; LA32-NEXT: lu12i.w $a1, 3
210 ; LA32-NEXT: ori $a1, $a1, 819
211 ; LA32-NEXT: and $a2, $a0, $a1
212 ; LA32-NEXT: srli.w $a0, $a0, 2
213 ; LA32-NEXT: and $a0, $a0, $a1
214 ; LA32-NEXT: add.w $a0, $a2, $a0
215 ; LA32-NEXT: srli.w $a1, $a0, 4
216 ; LA32-NEXT: add.w $a0, $a0, $a1
217 ; LA32-NEXT: bstrpick.w $a1, $a0, 11, 8
218 ; LA32-NEXT: andi $a0, $a0, 15
219 ; LA32-NEXT: add.w $a0, $a0, $a1
222 ; LA64-LABEL: test_ctpop_i16:
224 ; LA64-NEXT: srli.d $a1, $a0, 1
225 ; LA64-NEXT: lu12i.w $a2, 5
226 ; LA64-NEXT: ori $a2, $a2, 1365
227 ; LA64-NEXT: and $a1, $a1, $a2
228 ; LA64-NEXT: sub.d $a0, $a0, $a1
229 ; LA64-NEXT: lu12i.w $a1, 3
230 ; LA64-NEXT: ori $a1, $a1, 819
231 ; LA64-NEXT: and $a2, $a0, $a1
232 ; LA64-NEXT: srli.d $a0, $a0, 2
233 ; LA64-NEXT: and $a0, $a0, $a1
234 ; LA64-NEXT: add.d $a0, $a2, $a0
235 ; LA64-NEXT: srli.d $a1, $a0, 4
236 ; LA64-NEXT: add.d $a0, $a0, $a1
237 ; LA64-NEXT: bstrpick.d $a1, $a0, 11, 8
238 ; LA64-NEXT: andi $a0, $a0, 15
239 ; LA64-NEXT: add.d $a0, $a0, $a1
241 %1 = call i16 @llvm.ctpop.i16(i16 %a)
245 define i32 @test_ctpop_i32(i32 %a) nounwind {
246 ; LA32-LABEL: test_ctpop_i32:
248 ; LA32-NEXT: srli.w $a1, $a0, 1
249 ; LA32-NEXT: lu12i.w $a2, 349525
250 ; LA32-NEXT: ori $a2, $a2, 1365
251 ; LA32-NEXT: and $a1, $a1, $a2
252 ; LA32-NEXT: sub.w $a0, $a0, $a1
253 ; LA32-NEXT: lu12i.w $a1, 209715
254 ; LA32-NEXT: ori $a1, $a1, 819
255 ; LA32-NEXT: and $a2, $a0, $a1
256 ; LA32-NEXT: srli.w $a0, $a0, 2
257 ; LA32-NEXT: and $a0, $a0, $a1
258 ; LA32-NEXT: add.w $a0, $a2, $a0
259 ; LA32-NEXT: srli.w $a1, $a0, 4
260 ; LA32-NEXT: add.w $a0, $a0, $a1
261 ; LA32-NEXT: lu12i.w $a1, 61680
262 ; LA32-NEXT: ori $a1, $a1, 3855
263 ; LA32-NEXT: and $a0, $a0, $a1
264 ; LA32-NEXT: lu12i.w $a1, 4112
265 ; LA32-NEXT: ori $a1, $a1, 257
266 ; LA32-NEXT: mul.w $a0, $a0, $a1
267 ; LA32-NEXT: srli.w $a0, $a0, 24
270 ; LA64-LABEL: test_ctpop_i32:
272 ; LA64-NEXT: srli.d $a1, $a0, 1
273 ; LA64-NEXT: lu12i.w $a2, 349525
274 ; LA64-NEXT: ori $a2, $a2, 1365
275 ; LA64-NEXT: and $a1, $a1, $a2
276 ; LA64-NEXT: sub.d $a0, $a0, $a1
277 ; LA64-NEXT: lu12i.w $a1, 209715
278 ; LA64-NEXT: ori $a1, $a1, 819
279 ; LA64-NEXT: and $a2, $a0, $a1
280 ; LA64-NEXT: srli.d $a0, $a0, 2
281 ; LA64-NEXT: and $a0, $a0, $a1
282 ; LA64-NEXT: add.d $a0, $a2, $a0
283 ; LA64-NEXT: srli.d $a1, $a0, 4
284 ; LA64-NEXT: add.d $a0, $a0, $a1
285 ; LA64-NEXT: lu12i.w $a1, 61680
286 ; LA64-NEXT: ori $a1, $a1, 3855
287 ; LA64-NEXT: and $a0, $a0, $a1
288 ; LA64-NEXT: lu12i.w $a1, 4112
289 ; LA64-NEXT: ori $a1, $a1, 257
290 ; LA64-NEXT: mul.d $a0, $a0, $a1
291 ; LA64-NEXT: bstrpick.d $a0, $a0, 31, 24
293 %1 = call i32 @llvm.ctpop.i32(i32 %a)
297 define i64 @test_ctpop_i64(i64 %a) nounwind {
298 ; LA32-LABEL: test_ctpop_i64:
300 ; LA32-NEXT: srli.w $a2, $a1, 1
301 ; LA32-NEXT: lu12i.w $a3, 349525
302 ; LA32-NEXT: ori $a3, $a3, 1365
303 ; LA32-NEXT: and $a2, $a2, $a3
304 ; LA32-NEXT: sub.w $a1, $a1, $a2
305 ; LA32-NEXT: lu12i.w $a2, 209715
306 ; LA32-NEXT: ori $a2, $a2, 819
307 ; LA32-NEXT: and $a4, $a1, $a2
308 ; LA32-NEXT: srli.w $a1, $a1, 2
309 ; LA32-NEXT: and $a1, $a1, $a2
310 ; LA32-NEXT: add.w $a1, $a4, $a1
311 ; LA32-NEXT: srli.w $a4, $a1, 4
312 ; LA32-NEXT: add.w $a1, $a1, $a4
313 ; LA32-NEXT: lu12i.w $a4, 61680
314 ; LA32-NEXT: ori $a4, $a4, 3855
315 ; LA32-NEXT: and $a1, $a1, $a4
316 ; LA32-NEXT: lu12i.w $a5, 4112
317 ; LA32-NEXT: ori $a5, $a5, 257
318 ; LA32-NEXT: mul.w $a1, $a1, $a5
319 ; LA32-NEXT: srli.w $a1, $a1, 24
320 ; LA32-NEXT: srli.w $a6, $a0, 1
321 ; LA32-NEXT: and $a3, $a6, $a3
322 ; LA32-NEXT: sub.w $a0, $a0, $a3
323 ; LA32-NEXT: and $a3, $a0, $a2
324 ; LA32-NEXT: srli.w $a0, $a0, 2
325 ; LA32-NEXT: and $a0, $a0, $a2
326 ; LA32-NEXT: add.w $a0, $a3, $a0
327 ; LA32-NEXT: srli.w $a2, $a0, 4
328 ; LA32-NEXT: add.w $a0, $a0, $a2
329 ; LA32-NEXT: and $a0, $a0, $a4
330 ; LA32-NEXT: mul.w $a0, $a0, $a5
331 ; LA32-NEXT: srli.w $a0, $a0, 24
332 ; LA32-NEXT: add.w $a0, $a0, $a1
333 ; LA32-NEXT: move $a1, $zero
336 ; LA64-LABEL: test_ctpop_i64:
338 ; LA64-NEXT: srli.d $a1, $a0, 1
339 ; LA64-NEXT: lu12i.w $a2, 349525
340 ; LA64-NEXT: ori $a2, $a2, 1365
341 ; LA64-NEXT: lu32i.d $a2, 349525
342 ; LA64-NEXT: lu52i.d $a2, $a2, 1365
343 ; LA64-NEXT: and $a1, $a1, $a2
344 ; LA64-NEXT: sub.d $a0, $a0, $a1
345 ; LA64-NEXT: lu12i.w $a1, 209715
346 ; LA64-NEXT: ori $a1, $a1, 819
347 ; LA64-NEXT: lu32i.d $a1, 209715
348 ; LA64-NEXT: lu52i.d $a1, $a1, 819
349 ; LA64-NEXT: and $a2, $a0, $a1
350 ; LA64-NEXT: srli.d $a0, $a0, 2
351 ; LA64-NEXT: and $a0, $a0, $a1
352 ; LA64-NEXT: add.d $a0, $a2, $a0
353 ; LA64-NEXT: srli.d $a1, $a0, 4
354 ; LA64-NEXT: add.d $a0, $a0, $a1
355 ; LA64-NEXT: lu12i.w $a1, 61680
356 ; LA64-NEXT: ori $a1, $a1, 3855
357 ; LA64-NEXT: lu32i.d $a1, -61681
358 ; LA64-NEXT: lu52i.d $a1, $a1, 240
359 ; LA64-NEXT: and $a0, $a0, $a1
360 ; LA64-NEXT: lu12i.w $a1, 4112
361 ; LA64-NEXT: ori $a1, $a1, 257
362 ; LA64-NEXT: lu32i.d $a1, 65793
363 ; LA64-NEXT: lu52i.d $a1, $a1, 16
364 ; LA64-NEXT: mul.d $a0, $a0, $a1
365 ; LA64-NEXT: srli.d $a0, $a0, 56
367 %1 = call i64 @llvm.ctpop.i64(i64 %a)
371 define i8 @test_cttz_i8(i8 %a) nounwind {
372 ; LA32-LABEL: test_cttz_i8:
374 ; LA32-NEXT: ori $a0, $a0, 256
375 ; LA32-NEXT: ctz.w $a0, $a0
378 ; LA64-LABEL: test_cttz_i8:
380 ; LA64-NEXT: ori $a0, $a0, 256
381 ; LA64-NEXT: ctz.d $a0, $a0
383 %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false)
387 define i16 @test_cttz_i16(i16 %a) nounwind {
388 ; LA32-LABEL: test_cttz_i16:
390 ; LA32-NEXT: lu12i.w $a1, 16
391 ; LA32-NEXT: or $a0, $a0, $a1
392 ; LA32-NEXT: ctz.w $a0, $a0
395 ; LA64-LABEL: test_cttz_i16:
397 ; LA64-NEXT: lu12i.w $a1, 16
398 ; LA64-NEXT: or $a0, $a0, $a1
399 ; LA64-NEXT: ctz.d $a0, $a0
401 %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false)
405 define i32 @test_cttz_i32(i32 %a) nounwind {
406 ; LA32-LABEL: test_cttz_i32:
408 ; LA32-NEXT: ctz.w $a0, $a0
411 ; LA64-LABEL: test_cttz_i32:
413 ; LA64-NEXT: ctz.w $a0, $a0
415 %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
419 define i64 @test_cttz_i64(i64 %a) nounwind {
420 ; LA32-LABEL: test_cttz_i64:
422 ; LA32-NEXT: sltu $a2, $zero, $a0
423 ; LA32-NEXT: ctz.w $a0, $a0
424 ; LA32-NEXT: maskeqz $a0, $a0, $a2
425 ; LA32-NEXT: ctz.w $a1, $a1
426 ; LA32-NEXT: addi.w $a1, $a1, 32
427 ; LA32-NEXT: masknez $a1, $a1, $a2
428 ; LA32-NEXT: or $a0, $a0, $a1
429 ; LA32-NEXT: move $a1, $zero
432 ; LA64-LABEL: test_cttz_i64:
434 ; LA64-NEXT: ctz.d $a0, $a0
436 %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false)
440 define i8 @test_not_cttz_i8(i8 %a) nounwind {
441 ; LA32-LABEL: test_not_cttz_i8:
443 ; LA32-NEXT: ori $a1, $zero, 256
444 ; LA32-NEXT: orn $a0, $a1, $a0
445 ; LA32-NEXT: ctz.w $a0, $a0
448 ; LA64-LABEL: test_not_cttz_i8:
450 ; LA64-NEXT: ori $a1, $zero, 256
451 ; LA64-NEXT: orn $a0, $a1, $a0
452 ; LA64-NEXT: ctz.d $a0, $a0
455 %tmp = call i8 @llvm.cttz.i8(i8 %neg, i1 false)
459 define i16 @test_not_cttz_i16(i16 %a) nounwind {
460 ; LA32-LABEL: test_not_cttz_i16:
462 ; LA32-NEXT: lu12i.w $a1, 16
463 ; LA32-NEXT: orn $a0, $a1, $a0
464 ; LA32-NEXT: ctz.w $a0, $a0
467 ; LA64-LABEL: test_not_cttz_i16:
469 ; LA64-NEXT: lu12i.w $a1, 16
470 ; LA64-NEXT: orn $a0, $a1, $a0
471 ; LA64-NEXT: ctz.d $a0, $a0
473 %neg = xor i16 %a, -1
474 %tmp = call i16 @llvm.cttz.i16(i16 %neg, i1 false)
478 define i32 @test_not_cttz_i32(i32 %a) nounwind {
479 ; LA32-LABEL: test_not_cttz_i32:
481 ; LA32-NEXT: cto.w $a0, $a0
484 ; LA64-LABEL: test_not_cttz_i32:
486 ; LA64-NEXT: cto.w $a0, $a0
488 %neg = xor i32 %a, -1
489 %tmp = call i32 @llvm.cttz.i32(i32 %neg, i1 false)
493 define i64 @test_not_cttz_i64(i64 %a) nounwind {
494 ; LA32-LABEL: test_not_cttz_i64:
496 ; LA32-NEXT: nor $a2, $a0, $zero
497 ; LA32-NEXT: sltu $a2, $zero, $a2
498 ; LA32-NEXT: cto.w $a1, $a1
499 ; LA32-NEXT: addi.w $a1, $a1, 32
500 ; LA32-NEXT: masknez $a1, $a1, $a2
501 ; LA32-NEXT: cto.w $a0, $a0
502 ; LA32-NEXT: maskeqz $a0, $a0, $a2
503 ; LA32-NEXT: or $a0, $a0, $a1
504 ; LA32-NEXT: move $a1, $zero
507 ; LA64-LABEL: test_not_cttz_i64:
509 ; LA64-NEXT: cto.d $a0, $a0
511 %neg = xor i64 %a, -1
512 %tmp = call i64 @llvm.cttz.i64(i64 %neg, i1 false)