1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefixes=32
3 ; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefixes=32
4 ; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefixes=32R6
5 ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP
6 ; RUN: llc -march=mips -mcpu=mips64 -target-abi n64 < %s | FileCheck %s -check-prefixes=64
7 ; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s | FileCheck %s -check-prefixes=64
8 ; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s | FileCheck %s -check-prefixes=64R6
9 ; RUN: llc -march=mips -mattr=mips16 < %s | FileCheck %s -check-prefixes=16
11 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
13 ; 32: # %bb.0: # %entry
14 ; 32-NEXT: sra $1, $6, 31
17 ; 32-NEXT: madd $5, $4
23 ; 32R6: # %bb.0: # %entry
24 ; 32R6-NEXT: mul $1, $5, $4
25 ; 32R6-NEXT: addu $3, $1, $6
26 ; 32R6-NEXT: sltu $1, $3, $1
27 ; 32R6-NEXT: muh $2, $5, $4
28 ; 32R6-NEXT: sra $4, $6, 31
29 ; 32R6-NEXT: addu $2, $2, $4
31 ; 32R6-NEXT: addu $2, $2, $1
34 ; DSP: # %bb.0: # %entry
35 ; DSP-NEXT: sra $1, $6, 31
36 ; DSP-NEXT: mtlo $6, $ac0
37 ; DSP-NEXT: mthi $1, $ac0
38 ; DSP-NEXT: madd $ac0, $5, $4
39 ; DSP-NEXT: mfhi $2, $ac0
41 ; DSP-NEXT: mflo $3, $ac0
44 ; 64: # %bb.0: # %entry
45 ; 64-NEXT: sll $4, $4, 0
46 ; 64-NEXT: sll $5, $5, 0
47 ; 64-NEXT: dmult $5, $4
49 ; 64-NEXT: sll $6, $6, 0
51 ; 64-NEXT: daddu $2, $1, $6
54 ; 64R6: # %bb.0: # %entry
55 ; 64R6-NEXT: sll $4, $4, 0
56 ; 64R6-NEXT: sll $5, $5, 0
57 ; 64R6-NEXT: dmul $1, $5, $4
58 ; 64R6-NEXT: sll $6, $6, 0
60 ; 64R6-NEXT: daddu $2, $1, $6
63 ; 16: # %bb.0: # %entry
64 ; 16-NEXT: mult $5, $4
67 ; 16-NEXT: sra $4, $6, 31
68 ; 16-NEXT: addu $4, $3, $4
69 ; 16-NEXT: addu $3, $2, $6
70 ; 16-NEXT: sltu $3, $2
71 ; 16-NEXT: move $2, $24
72 ; 16-NEXT: addu $2, $4, $2
75 %conv = sext i32 %a to i64
76 %conv2 = sext i32 %b to i64
77 %mul = mul nsw i64 %conv2, %conv
78 %conv4 = sext i32 %c to i64
79 %add = add nsw i64 %mul, %conv4
83 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
85 ; 32: # %bb.0: # %entry
86 ; 32-NEXT: addiu $1, $zero, 0
89 ; 32-NEXT: maddu $5, $4
95 ; 32R6: # %bb.0: # %entry
96 ; 32R6-NEXT: mul $1, $5, $4
97 ; 32R6-NEXT: addu $3, $1, $6
98 ; 32R6-NEXT: sltu $1, $3, $1
99 ; 32R6-NEXT: muhu $2, $5, $4
101 ; 32R6-NEXT: addu $2, $2, $1
104 ; DSP: # %bb.0: # %entry
105 ; DSP-NEXT: addiu $1, $zero, 0
106 ; DSP-NEXT: mtlo $6, $ac0
107 ; DSP-NEXT: mthi $1, $ac0
108 ; DSP-NEXT: maddu $ac0, $5, $4
109 ; DSP-NEXT: mfhi $2, $ac0
111 ; DSP-NEXT: mflo $3, $ac0
114 ; 64: # %bb.0: # %entry
115 ; 64-NEXT: dmult $5, $4
118 ; 64-NEXT: daddu $2, $1, $6
121 ; 64R6: # %bb.0: # %entry
122 ; 64R6-NEXT: dmul $1, $5, $4
124 ; 64R6-NEXT: daddu $2, $1, $6
127 ; 16: # %bb.0: # %entry
128 ; 16-NEXT: multu $5, $4
131 ; 16-NEXT: addu $3, $2, $6
132 ; 16-NEXT: sltu $3, $2
133 ; 16-NEXT: move $2, $24
134 ; 16-NEXT: addu $2, $4, $2
137 %conv = zext i32 %a to i64
138 %conv2 = zext i32 %b to i64
139 %mul = mul nsw i64 %conv2, %conv
140 %conv4 = zext i32 %c to i64
141 %add = add nsw i64 %mul, %conv4
145 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
147 ; 32: # %bb.0: # %entry
150 ; 32-NEXT: madd $5, $4
156 ; 32R6: # %bb.0: # %entry
157 ; 32R6-NEXT: mul $1, $5, $4
158 ; 32R6-NEXT: addu $3, $1, $7
159 ; 32R6-NEXT: sltu $1, $3, $1
160 ; 32R6-NEXT: muh $2, $5, $4
161 ; 32R6-NEXT: addu $2, $2, $6
163 ; 32R6-NEXT: addu $2, $2, $1
166 ; DSP: # %bb.0: # %entry
167 ; DSP-NEXT: mtlo $7, $ac0
168 ; DSP-NEXT: mthi $6, $ac0
169 ; DSP-NEXT: madd $ac0, $5, $4
170 ; DSP-NEXT: mfhi $2, $ac0
172 ; DSP-NEXT: mflo $3, $ac0
175 ; 64: # %bb.0: # %entry
176 ; 64-NEXT: sll $4, $4, 0
177 ; 64-NEXT: sll $5, $5, 0
178 ; 64-NEXT: dmult $5, $4
181 ; 64-NEXT: daddu $2, $1, $6
184 ; 64R6: # %bb.0: # %entry
185 ; 64R6-NEXT: sll $4, $4, 0
186 ; 64R6-NEXT: sll $5, $5, 0
187 ; 64R6-NEXT: dmul $1, $5, $4
189 ; 64R6-NEXT: daddu $2, $1, $6
192 ; 16: # %bb.0: # %entry
193 ; 16-NEXT: mult $5, $4
196 ; 16-NEXT: addu $4, $3, $6
197 ; 16-NEXT: addu $3, $2, $7
198 ; 16-NEXT: sltu $3, $2
199 ; 16-NEXT: move $2, $24
200 ; 16-NEXT: addu $2, $4, $2
203 %conv = sext i32 %a to i64
204 %conv2 = sext i32 %b to i64
205 %mul = mul nsw i64 %conv2, %conv
206 %add = add nsw i64 %mul, %c
210 define i32 @madd4(i32 %a, i32 %b, i32 %c) {
212 ; 32: # %bb.0: # %entry
213 ; 32-NEXT: mul $1, $4, $5
215 ; 32-NEXT: addu $2, $6, $1
218 ; 32R6: # %bb.0: # %entry
219 ; 32R6-NEXT: mul $1, $4, $5
221 ; 32R6-NEXT: addu $2, $6, $1
224 ; DSP: # %bb.0: # %entry
225 ; DSP-NEXT: mul $1, $4, $5
227 ; DSP-NEXT: addu $2, $6, $1
230 ; 64: # %bb.0: # %entry
231 ; 64-NEXT: sll $1, $5, 0
232 ; 64-NEXT: sll $2, $4, 0
233 ; 64-NEXT: mul $1, $2, $1
234 ; 64-NEXT: sll $2, $6, 0
236 ; 64-NEXT: addu $2, $2, $1
239 ; 64R6: # %bb.0: # %entry
240 ; 64R6-NEXT: sll $1, $5, 0
241 ; 64R6-NEXT: sll $2, $4, 0
242 ; 64R6-NEXT: mul $1, $2, $1
243 ; 64R6-NEXT: sll $2, $6, 0
245 ; 64R6-NEXT: addu $2, $2, $1
248 ; 16: # %bb.0: # %entry
249 ; 16-NEXT: mult $4, $5
251 ; 16-NEXT: addu $2, $6, $2
254 %mul = mul nsw i32 %a, %b
255 %add = add nsw i32 %c, %mul
260 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
262 ; 32: # %bb.0: # %entry
263 ; 32-NEXT: sra $1, $6, 31
266 ; 32-NEXT: msub $5, $4
272 ; 32R6: # %bb.0: # %entry
273 ; 32R6-NEXT: mul $1, $5, $4
274 ; 32R6-NEXT: sltu $2, $6, $1
275 ; 32R6-NEXT: muh $3, $5, $4
276 ; 32R6-NEXT: sra $4, $6, 31
277 ; 32R6-NEXT: subu $3, $4, $3
278 ; 32R6-NEXT: subu $2, $3, $2
280 ; 32R6-NEXT: subu $3, $6, $1
283 ; DSP: # %bb.0: # %entry
284 ; DSP-NEXT: sra $1, $6, 31
285 ; DSP-NEXT: mtlo $6, $ac0
286 ; DSP-NEXT: mthi $1, $ac0
287 ; DSP-NEXT: msub $ac0, $5, $4
288 ; DSP-NEXT: mfhi $2, $ac0
290 ; DSP-NEXT: mflo $3, $ac0
293 ; 64: # %bb.0: # %entry
294 ; 64-NEXT: sll $4, $4, 0
295 ; 64-NEXT: sll $5, $5, 0
296 ; 64-NEXT: dmult $5, $4
298 ; 64-NEXT: sll $6, $6, 0
300 ; 64-NEXT: dsubu $2, $6, $1
303 ; 64R6: # %bb.0: # %entry
304 ; 64R6-NEXT: sll $4, $4, 0
305 ; 64R6-NEXT: sll $5, $5, 0
306 ; 64R6-NEXT: dmul $1, $5, $4
307 ; 64R6-NEXT: sll $6, $6, 0
309 ; 64R6-NEXT: dsubu $2, $6, $1
312 ; 16: # %bb.0: # %entry
313 ; 16-NEXT: mult $5, $4
316 ; 16-NEXT: subu $3, $6, $2
317 ; 16-NEXT: sltu $6, $2
318 ; 16-NEXT: move $2, $24
319 ; 16-NEXT: sra $5, $6, 31
320 ; 16-NEXT: subu $4, $5, $4
321 ; 16-NEXT: subu $2, $4, $2
324 %conv = sext i32 %c to i64
325 %conv2 = sext i32 %a to i64
326 %conv4 = sext i32 %b to i64
327 %mul = mul nsw i64 %conv4, %conv2
328 %sub = sub nsw i64 %conv, %mul
332 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
334 ; 32: # %bb.0: # %entry
335 ; 32-NEXT: addiu $1, $zero, 0
338 ; 32-NEXT: msubu $5, $4
344 ; 32R6: # %bb.0: # %entry
345 ; 32R6-NEXT: muhu $1, $5, $4
346 ; 32R6-NEXT: mul $3, $5, $4
347 ; 32R6-NEXT: sltu $2, $6, $3
348 ; 32R6-NEXT: addu $1, $1, $2
349 ; 32R6-NEXT: negu $2, $1
351 ; 32R6-NEXT: subu $3, $6, $3
354 ; DSP: # %bb.0: # %entry
355 ; DSP-NEXT: addiu $1, $zero, 0
356 ; DSP-NEXT: mtlo $6, $ac0
357 ; DSP-NEXT: mthi $1, $ac0
358 ; DSP-NEXT: msubu $ac0, $5, $4
359 ; DSP-NEXT: mfhi $2, $ac0
361 ; DSP-NEXT: mflo $3, $ac0
364 ; 64: # %bb.0: # %entry
365 ; 64-NEXT: dmult $5, $4
368 ; 64-NEXT: dsubu $2, $6, $1
371 ; 64R6: # %bb.0: # %entry
372 ; 64R6-NEXT: dmul $1, $5, $4
374 ; 64R6-NEXT: dsubu $2, $6, $1
377 ; 16: # %bb.0: # %entry
378 ; 16-NEXT: multu $5, $4
381 ; 16-NEXT: sltu $6, $2
382 ; 16-NEXT: move $4, $24
383 ; 16-NEXT: addu $4, $3, $4
384 ; 16-NEXT: subu $3, $6, $2
385 ; 16-NEXT: neg $2, $4
388 %conv = zext i32 %c to i64
389 %conv2 = zext i32 %a to i64
390 %conv4 = zext i32 %b to i64
391 %mul = mul nsw i64 %conv4, %conv2
392 %sub = sub nsw i64 %conv, %mul
396 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
398 ; 32: # %bb.0: # %entry
401 ; 32-NEXT: msub $5, $4
407 ; 32R6: # %bb.0: # %entry
408 ; 32R6-NEXT: mul $1, $5, $4
409 ; 32R6-NEXT: sltu $2, $7, $1
410 ; 32R6-NEXT: muh $3, $5, $4
411 ; 32R6-NEXT: subu $3, $6, $3
412 ; 32R6-NEXT: subu $2, $3, $2
414 ; 32R6-NEXT: subu $3, $7, $1
417 ; DSP: # %bb.0: # %entry
418 ; DSP-NEXT: mtlo $7, $ac0
419 ; DSP-NEXT: mthi $6, $ac0
420 ; DSP-NEXT: msub $ac0, $5, $4
421 ; DSP-NEXT: mfhi $2, $ac0
423 ; DSP-NEXT: mflo $3, $ac0
426 ; 64: # %bb.0: # %entry
427 ; 64-NEXT: sll $4, $4, 0
428 ; 64-NEXT: sll $5, $5, 0
429 ; 64-NEXT: dmult $5, $4
432 ; 64-NEXT: dsubu $2, $6, $1
435 ; 64R6: # %bb.0: # %entry
436 ; 64R6-NEXT: sll $4, $4, 0
437 ; 64R6-NEXT: sll $5, $5, 0
438 ; 64R6-NEXT: dmul $1, $5, $4
440 ; 64R6-NEXT: dsubu $2, $6, $1
443 ; 16: # %bb.0: # %entry
444 ; 16-NEXT: mult $5, $4
447 ; 16-NEXT: subu $3, $7, $2
448 ; 16-NEXT: sltu $7, $2
449 ; 16-NEXT: move $2, $24
450 ; 16-NEXT: subu $4, $6, $4
451 ; 16-NEXT: subu $2, $4, $2
454 %conv = sext i32 %a to i64
455 %conv3 = sext i32 %b to i64
456 %mul = mul nsw i64 %conv3, %conv
457 %sub = sub nsw i64 %c, %mul
461 define i32 @msub4(i32 %a, i32 %b, i32 %c) {
463 ; 32: # %bb.0: # %entry
464 ; 32-NEXT: mul $1, $4, $5
466 ; 32-NEXT: subu $2, $6, $1
469 ; 32R6: # %bb.0: # %entry
470 ; 32R6-NEXT: mul $1, $4, $5
472 ; 32R6-NEXT: subu $2, $6, $1
475 ; DSP: # %bb.0: # %entry
476 ; DSP-NEXT: mul $1, $4, $5
478 ; DSP-NEXT: subu $2, $6, $1
481 ; 64: # %bb.0: # %entry
482 ; 64-NEXT: sll $1, $5, 0
483 ; 64-NEXT: sll $2, $4, 0
484 ; 64-NEXT: mul $1, $2, $1
485 ; 64-NEXT: sll $2, $6, 0
487 ; 64-NEXT: subu $2, $2, $1
490 ; 64R6: # %bb.0: # %entry
491 ; 64R6-NEXT: sll $1, $5, 0
492 ; 64R6-NEXT: sll $2, $4, 0
493 ; 64R6-NEXT: mul $1, $2, $1
494 ; 64R6-NEXT: sll $2, $6, 0
496 ; 64R6-NEXT: subu $2, $2, $1
499 ; 16: # %bb.0: # %entry
500 ; 16-NEXT: mult $4, $5
502 ; 16-NEXT: subu $2, $6, $2
505 %mul = mul nsw i32 %a, %b
506 %sub = sub nsw i32 %c, %mul
511 define i64 @msub5(i32 %a, i32 %b, i32 %c) {
513 ; 32: # %bb.0: # %entry
514 ; 32-NEXT: mult $5, $4
517 ; 32-NEXT: sltu $2, $3, $6
518 ; 32-NEXT: sra $4, $6, 31
519 ; 32-NEXT: subu $1, $1, $4
520 ; 32-NEXT: subu $2, $1, $2
522 ; 32-NEXT: subu $3, $3, $6
525 ; 32R6: # %bb.0: # %entry
526 ; 32R6-NEXT: mul $1, $5, $4
527 ; 32R6-NEXT: sltu $2, $1, $6
528 ; 32R6-NEXT: muh $3, $5, $4
529 ; 32R6-NEXT: sra $4, $6, 31
530 ; 32R6-NEXT: subu $3, $3, $4
531 ; 32R6-NEXT: subu $2, $3, $2
533 ; 32R6-NEXT: subu $3, $1, $6
536 ; DSP: # %bb.0: # %entry
537 ; DSP-NEXT: mult $ac0, $5, $4
538 ; DSP-NEXT: mfhi $1, $ac0
539 ; DSP-NEXT: mflo $3, $ac0
540 ; DSP-NEXT: sltu $2, $3, $6
541 ; DSP-NEXT: sra $4, $6, 31
542 ; DSP-NEXT: subu $1, $1, $4
543 ; DSP-NEXT: subu $2, $1, $2
545 ; DSP-NEXT: subu $3, $3, $6
548 ; 64: # %bb.0: # %entry
549 ; 64-NEXT: sll $4, $4, 0
550 ; 64-NEXT: sll $5, $5, 0
551 ; 64-NEXT: dmult $5, $4
553 ; 64-NEXT: sll $6, $6, 0
555 ; 64-NEXT: dsubu $2, $1, $6
558 ; 64R6: # %bb.0: # %entry
559 ; 64R6-NEXT: sll $4, $4, 0
560 ; 64R6-NEXT: sll $5, $5, 0
561 ; 64R6-NEXT: dmul $1, $5, $4
562 ; 64R6-NEXT: sll $6, $6, 0
564 ; 64R6-NEXT: dsubu $2, $1, $6
567 ; 16: # %bb.0: # %entry
568 ; 16-NEXT: mult $5, $4
571 ; 16-NEXT: subu $3, $2, $6
572 ; 16-NEXT: sltu $2, $6
573 ; 16-NEXT: move $2, $24
574 ; 16-NEXT: sra $5, $6, 31
575 ; 16-NEXT: subu $4, $4, $5
576 ; 16-NEXT: subu $2, $4, $2
579 %conv = sext i32 %a to i64
580 %conv3 = sext i32 %b to i64
581 %conv4 = sext i32 %c to i64
582 %mul = mul nsw i64 %conv3, %conv
583 %sub = sub nsw i64 %mul, %conv4