Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / GlobalISel / alu-roundtrip.ll
blobc503d6541b0a5778f76a038e212e30b378e419c8
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+m -global-isel -verify-machineinstrs < %s \
3 ; RUN:   -riscv-enable-copy-propagation=false | FileCheck %s --check-prefix=RV32IM
4 ; RUN: llc -mtriple=riscv64 -mattr=+m -global-isel -verify-machineinstrs < %s \
5 ; RUN:   -riscv-enable-copy-propagation=false | FileCheck %s --check-prefix=RV64IM
7 ; Extends to 32 bits exhaustively tested for add only.
9 define i8 @add_i8(i8 %a, i8 %b) {
10 ; RV32IM-LABEL: add_i8:
11 ; RV32IM:       # %bb.0: # %entry
12 ; RV32IM-NEXT:    add a0, a0, a1
13 ; RV32IM-NEXT:    ret
15 ; RV64IM-LABEL: add_i8:
16 ; RV64IM:       # %bb.0: # %entry
17 ; RV64IM-NEXT:    addw a0, a0, a1
18 ; RV64IM-NEXT:    ret
19 entry:
20   %0 = add i8 %a, %b
21   ret i8 %0
24 define i32 @add_i8_signext_i32(i8 %a, i8 %b) {
25 ; RV32IM-LABEL: add_i8_signext_i32:
26 ; RV32IM:       # %bb.0: # %entry
27 ; RV32IM-NEXT:    slli a0, a0, 24
28 ; RV32IM-NEXT:    srai a0, a0, 24
29 ; RV32IM-NEXT:    slli a1, a1, 24
30 ; RV32IM-NEXT:    srai a1, a1, 24
31 ; RV32IM-NEXT:    add a0, a0, a1
32 ; RV32IM-NEXT:    ret
34 ; RV64IM-LABEL: add_i8_signext_i32:
35 ; RV64IM:       # %bb.0: # %entry
36 ; RV64IM-NEXT:    slli a0, a0, 24
37 ; RV64IM-NEXT:    sraiw a0, a0, 24
38 ; RV64IM-NEXT:    slli a1, a1, 24
39 ; RV64IM-NEXT:    sraiw a1, a1, 24
40 ; RV64IM-NEXT:    addw a0, a0, a1
41 ; RV64IM-NEXT:    ret
42 entry:
43   %0 = sext i8 %a to i32
44   %1 = sext i8 %b to i32
45   %2 = add i32 %0, %1
46   ret i32 %2
49 define i32 @add_i8_zeroext_i32(i8 %a, i8 %b) {
50 ; RV32IM-LABEL: add_i8_zeroext_i32:
51 ; RV32IM:       # %bb.0: # %entry
52 ; RV32IM-NEXT:    andi a0, a0, 255
53 ; RV32IM-NEXT:    andi a1, a1, 255
54 ; RV32IM-NEXT:    add a0, a0, a1
55 ; RV32IM-NEXT:    ret
57 ; RV64IM-LABEL: add_i8_zeroext_i32:
58 ; RV64IM:       # %bb.0: # %entry
59 ; RV64IM-NEXT:    andi a0, a0, 255
60 ; RV64IM-NEXT:    andi a1, a1, 255
61 ; RV64IM-NEXT:    addw a0, a0, a1
62 ; RV64IM-NEXT:    ret
63 entry:
64   %0 = zext i8 %a to i32
65   %1 = zext i8 %b to i32
66   %2 = add i32 %0, %1
67   ret i32 %2
70 ; TODO: Handle G_IMPLICIT_DEF, which is needed to have i8 -> i64 extends working
71 ; on RV32.
73 define i32 @add_i32(i32 %a, i32 %b) {
74 ; RV32IM-LABEL: add_i32:
75 ; RV32IM:       # %bb.0: # %entry
76 ; RV32IM-NEXT:    add a0, a0, a1
77 ; RV32IM-NEXT:    ret
79 ; RV64IM-LABEL: add_i32:
80 ; RV64IM:       # %bb.0: # %entry
81 ; RV64IM-NEXT:    addw a0, a0, a1
82 ; RV64IM-NEXT:    ret
83 entry:
84   %0 = add i32 %a, %b
85   ret i32 %0
88 define i32 @addi_i32(i32 %a) {
89 ; RV32IM-LABEL: addi_i32:
90 ; RV32IM:       # %bb.0: # %entry
91 ; RV32IM-NEXT:    addi a0, a0, 1234
92 ; RV32IM-NEXT:    ret
94 ; RV64IM-LABEL: addi_i32:
95 ; RV64IM:       # %bb.0: # %entry
96 ; RV64IM-NEXT:    addiw a0, a0, 1234
97 ; RV64IM-NEXT:    ret
98 entry:
99   %0 = add i32 %a, 1234
100   ret i32 %0
103 define i32 @sub_i32(i32 %a, i32 %b) {
104 ; RV32IM-LABEL: sub_i32:
105 ; RV32IM:       # %bb.0: # %entry
106 ; RV32IM-NEXT:    sub a0, a0, a1
107 ; RV32IM-NEXT:    ret
109 ; RV64IM-LABEL: sub_i32:
110 ; RV64IM:       # %bb.0: # %entry
111 ; RV64IM-NEXT:    subw a0, a0, a1
112 ; RV64IM-NEXT:    ret
113 entry:
114   %0 = sub i32 %a, %b
115   ret i32 %0
118 define i32 @subi_i32(i32 %a) {
119 ; RV32IM-LABEL: subi_i32:
120 ; RV32IM:       # %bb.0: # %entry
121 ; RV32IM-NEXT:    addi a0, a0, -1234
122 ; RV32IM-NEXT:    ret
124 ; RV64IM-LABEL: subi_i32:
125 ; RV64IM:       # %bb.0: # %entry
126 ; RV64IM-NEXT:    addiw a0, a0, -1234
127 ; RV64IM-NEXT:    ret
128 entry:
129   %0 = sub i32 %a, 1234
130   ret i32 %0
133 define i32 @neg_i32(i32 %a) {
134 ; RV32IM-LABEL: neg_i32:
135 ; RV32IM:       # %bb.0: # %entry
136 ; RV32IM-NEXT:    neg a0, a0
137 ; RV32IM-NEXT:    ret
139 ; RV64IM-LABEL: neg_i32:
140 ; RV64IM:       # %bb.0: # %entry
141 ; RV64IM-NEXT:    negw a0, a0
142 ; RV64IM-NEXT:    ret
143 entry:
144   %0 = sub i32 0, %a
145   ret i32 %0
148 define i32 @sll_i32(i32 %a, i32 %b) {
149 ; RV32IM-LABEL: sll_i32:
150 ; RV32IM:       # %bb.0: # %entry
151 ; RV32IM-NEXT:    sll a0, a0, a1
152 ; RV32IM-NEXT:    ret
154 ; RV64IM-LABEL: sll_i32:
155 ; RV64IM:       # %bb.0: # %entry
156 ; RV64IM-NEXT:    sllw a0, a0, a1
157 ; RV64IM-NEXT:    ret
158 entry:
159   %0 = shl i32 %a, %b
160   ret i32 %0
163 define i32 @slli_i32(i32 %a) {
164 ; RV32IM-LABEL: slli_i32:
165 ; RV32IM:       # %bb.0: # %entry
166 ; RV32IM-NEXT:    slli a0, a0, 11
167 ; RV32IM-NEXT:    ret
169 ; RV64IM-LABEL: slli_i32:
170 ; RV64IM:       # %bb.0: # %entry
171 ; RV64IM-NEXT:    slliw a0, a0, 11
172 ; RV64IM-NEXT:    ret
173 entry:
174   %0 = shl i32 %a, 11
175   ret i32 %0
178 define i32 @sra_i32(i32 %a, i32 %b) {
179 ; RV32IM-LABEL: sra_i32:
180 ; RV32IM:       # %bb.0: # %entry
181 ; RV32IM-NEXT:    sra a0, a0, a1
182 ; RV32IM-NEXT:    ret
184 ; RV64IM-LABEL: sra_i32:
185 ; RV64IM:       # %bb.0: # %entry
186 ; RV64IM-NEXT:    sraw a0, a0, a1
187 ; RV64IM-NEXT:    ret
188 entry:
189   %0 = ashr i32 %a, %b
190   ret i32 %0
193 define i32 @srai_i32(i32 %a) {
194 ; RV32IM-LABEL: srai_i32:
195 ; RV32IM:       # %bb.0: # %entry
196 ; RV32IM-NEXT:    srai a0, a0, 17
197 ; RV32IM-NEXT:    ret
199 ; RV64IM-LABEL: srai_i32:
200 ; RV64IM:       # %bb.0: # %entry
201 ; RV64IM-NEXT:    sraiw a0, a0, 17
202 ; RV64IM-NEXT:    ret
203 entry:
204   %0 = ashr i32 %a, 17
205   ret i32 %0
208 define i32 @srl_i32(i32 %a, i32 %b) {
209 ; RV32IM-LABEL: srl_i32:
210 ; RV32IM:       # %bb.0: # %entry
211 ; RV32IM-NEXT:    srl a0, a0, a1
212 ; RV32IM-NEXT:    ret
214 ; RV64IM-LABEL: srl_i32:
215 ; RV64IM:       # %bb.0: # %entry
216 ; RV64IM-NEXT:    srlw a0, a0, a1
217 ; RV64IM-NEXT:    ret
218 entry:
219   %0 = lshr i32 %a, %b
220   ret i32 %0
223 define i32 @srli_i32(i32 %a, i32 %b) {
224 ; RV32IM-LABEL: srli_i32:
225 ; RV32IM:       # %bb.0: # %entry
226 ; RV32IM-NEXT:    srli a0, a0, 23
227 ; RV32IM-NEXT:    ret
229 ; RV64IM-LABEL: srli_i32:
230 ; RV64IM:       # %bb.0: # %entry
231 ; RV64IM-NEXT:    srliw a0, a0, 23
232 ; RV64IM-NEXT:    ret
233 entry:
234   %0 = lshr i32 %a, 23
235   ret i32 %0
238 define i32 @and_i32(i32 %a, i32 %b) {
239 ; RV32IM-LABEL: and_i32:
240 ; RV32IM:       # %bb.0: # %entry
241 ; RV32IM-NEXT:    and a0, a0, a1
242 ; RV32IM-NEXT:    ret
244 ; RV64IM-LABEL: and_i32:
245 ; RV64IM:       # %bb.0: # %entry
246 ; RV64IM-NEXT:    and a0, a0, a1
247 ; RV64IM-NEXT:    ret
248 entry:
249   %0 = and i32 %a, %b
250   ret i32 %0
253 define i32 @andi_i32(i32 %a) {
254 ; RV32IM-LABEL: andi_i32:
255 ; RV32IM:       # %bb.0: # %entry
256 ; RV32IM-NEXT:    andi a0, a0, 1234
257 ; RV32IM-NEXT:    ret
259 ; RV64IM-LABEL: andi_i32:
260 ; RV64IM:       # %bb.0: # %entry
261 ; RV64IM-NEXT:    andi a0, a0, 1234
262 ; RV64IM-NEXT:    ret
263 entry:
264   %0 = and i32 %a, 1234
265   ret i32 %0
268 define i32 @or_i32(i32 %a, i32 %b) {
269 ; RV32IM-LABEL: or_i32:
270 ; RV32IM:       # %bb.0: # %entry
271 ; RV32IM-NEXT:    or a0, a0, a1
272 ; RV32IM-NEXT:    ret
274 ; RV64IM-LABEL: or_i32:
275 ; RV64IM:       # %bb.0: # %entry
276 ; RV64IM-NEXT:    or a0, a0, a1
277 ; RV64IM-NEXT:    ret
278 entry:
279   %0 = or i32 %a, %b
280   ret i32 %0
283 define i32 @ori_i32(i32 %a) {
284 ; RV32IM-LABEL: ori_i32:
285 ; RV32IM:       # %bb.0: # %entry
286 ; RV32IM-NEXT:    ori a0, a0, 1234
287 ; RV32IM-NEXT:    ret
289 ; RV64IM-LABEL: ori_i32:
290 ; RV64IM:       # %bb.0: # %entry
291 ; RV64IM-NEXT:    ori a0, a0, 1234
292 ; RV64IM-NEXT:    ret
293 entry:
294   %0 = or i32 %a, 1234
295   ret i32 %0
298 define i32 @xor_i32(i32 %a, i32 %b) {
299 ; RV32IM-LABEL: xor_i32:
300 ; RV32IM:       # %bb.0: # %entry
301 ; RV32IM-NEXT:    xor a0, a0, a1
302 ; RV32IM-NEXT:    ret
304 ; RV64IM-LABEL: xor_i32:
305 ; RV64IM:       # %bb.0: # %entry
306 ; RV64IM-NEXT:    xor a0, a0, a1
307 ; RV64IM-NEXT:    ret
308 entry:
309   %0 = xor i32 %a, %b
310   ret i32 %0
313 define i32 @xori_i32(i32 %a, i32 %b) {
314 ; RV32IM-LABEL: xori_i32:
315 ; RV32IM:       # %bb.0: # %entry
316 ; RV32IM-NEXT:    xori a0, a0, 1234
317 ; RV32IM-NEXT:    ret
319 ; RV64IM-LABEL: xori_i32:
320 ; RV64IM:       # %bb.0: # %entry
321 ; RV64IM-NEXT:    xori a0, a0, 1234
322 ; RV64IM-NEXT:    ret
323 entry:
324   %0 = xor i32 %a, 1234
325   ret i32 %0
328 define i32 @mul_i32(i32 %a, i32 %b) {
329 ; RV32IM-LABEL: mul_i32:
330 ; RV32IM:       # %bb.0: # %entry
331 ; RV32IM-NEXT:    mul a0, a0, a1
332 ; RV32IM-NEXT:    ret
334 ; RV64IM-LABEL: mul_i32:
335 ; RV64IM:       # %bb.0: # %entry
336 ; RV64IM-NEXT:    mulw a0, a0, a1
337 ; RV64IM-NEXT:    ret
338 entry:
339   %0 = mul i32 %a, %b
340   ret i32 %0
343 define i32 @sdiv_i32(i32 %a, i32 %b) {
344 ; RV32IM-LABEL: sdiv_i32:
345 ; RV32IM:       # %bb.0: # %entry
346 ; RV32IM-NEXT:    div a0, a0, a1
347 ; RV32IM-NEXT:    ret
349 ; RV64IM-LABEL: sdiv_i32:
350 ; RV64IM:       # %bb.0: # %entry
351 ; RV64IM-NEXT:    divw a0, a0, a1
352 ; RV64IM-NEXT:    ret
353 entry:
354   %0 = sdiv i32 %a, %b
355   ret i32 %0
358 define i32 @srem_i32(i32 %a, i32 %b) {
359 ; RV32IM-LABEL: srem_i32:
360 ; RV32IM:       # %bb.0: # %entry
361 ; RV32IM-NEXT:    rem a0, a0, a1
362 ; RV32IM-NEXT:    ret
364 ; RV64IM-LABEL: srem_i32:
365 ; RV64IM:       # %bb.0: # %entry
366 ; RV64IM-NEXT:    remw a0, a0, a1
367 ; RV64IM-NEXT:    ret
368 entry:
369   %0 = srem i32 %a, %b
370   ret i32 %0
373 define i32 @udiv_i32(i32 %a, i32 %b) {
374 ; RV32IM-LABEL: udiv_i32:
375 ; RV32IM:       # %bb.0: # %entry
376 ; RV32IM-NEXT:    divu a0, a0, a1
377 ; RV32IM-NEXT:    ret
379 ; RV64IM-LABEL: udiv_i32:
380 ; RV64IM:       # %bb.0: # %entry
381 ; RV64IM-NEXT:    divuw a0, a0, a1
382 ; RV64IM-NEXT:    ret
383 entry:
384   %0 = udiv i32 %a, %b
385   ret i32 %0
388 define i32 @urem_i32(i32 %a, i32 %b) {
389 ; RV32IM-LABEL: urem_i32:
390 ; RV32IM:       # %bb.0: # %entry
391 ; RV32IM-NEXT:    remu a0, a0, a1
392 ; RV32IM-NEXT:    ret
394 ; RV64IM-LABEL: urem_i32:
395 ; RV64IM:       # %bb.0: # %entry
396 ; RV64IM-NEXT:    remuw a0, a0, a1
397 ; RV64IM-NEXT:    ret
398 entry:
399   %0 = urem i32 %a, %b
400   ret i32 %0
403 define i64 @add_i64(i64 %a, i64 %b) {
404 ; RV32IM-LABEL: add_i64:
405 ; RV32IM:       # %bb.0: # %entry
406 ; RV32IM-NEXT:    add a0, a0, a2
407 ; RV32IM-NEXT:    sltu a2, a0, a2
408 ; RV32IM-NEXT:    add a1, a1, a3
409 ; RV32IM-NEXT:    add a1, a1, a2
410 ; RV32IM-NEXT:    ret
412 ; RV64IM-LABEL: add_i64:
413 ; RV64IM:       # %bb.0: # %entry
414 ; RV64IM-NEXT:    add a0, a0, a1
415 ; RV64IM-NEXT:    ret
416 entry:
417   %0 = add i64 %a, %b
418   ret i64 %0
421 define i64 @addi_i64(i64 %a) {
422 ; RV32IM-LABEL: addi_i64:
423 ; RV32IM:       # %bb.0: # %entry
424 ; RV32IM-NEXT:    addi a0, a0, 1234
425 ; RV32IM-NEXT:    sltiu a2, a0, 1234
426 ; RV32IM-NEXT:    add a1, a1, a2
427 ; RV32IM-NEXT:    ret
429 ; RV64IM-LABEL: addi_i64:
430 ; RV64IM:       # %bb.0: # %entry
431 ; RV64IM-NEXT:    addi a0, a0, 1234
432 ; RV64IM-NEXT:    ret
433 entry:
434   %0 = add i64 %a, 1234
435   ret i64 %0
438 define i64 @sub_i64(i64 %a, i64 %b) {
439 ; RV32IM-LABEL: sub_i64:
440 ; RV32IM:       # %bb.0: # %entry
441 ; RV32IM-NEXT:    sub a4, a0, a2
442 ; RV32IM-NEXT:    sltu a0, a0, a2
443 ; RV32IM-NEXT:    sub a1, a1, a3
444 ; RV32IM-NEXT:    sub a1, a1, a0
445 ; RV32IM-NEXT:    mv a0, a4
446 ; RV32IM-NEXT:    ret
448 ; RV64IM-LABEL: sub_i64:
449 ; RV64IM:       # %bb.0: # %entry
450 ; RV64IM-NEXT:    sub a0, a0, a1
451 ; RV64IM-NEXT:    ret
452 entry:
453   %0 = sub i64 %a, %b
454   ret i64 %0
457 define i64 @subi_i64(i64 %a) {
458 ; RV32IM-LABEL: subi_i64:
459 ; RV32IM:       # %bb.0: # %entry
460 ; RV32IM-NEXT:    lui a2, 301
461 ; RV32IM-NEXT:    addi a3, a2, 1548
462 ; RV32IM-NEXT:    sub a2, a0, a3
463 ; RV32IM-NEXT:    sltu a0, a0, a3
464 ; RV32IM-NEXT:    sub a1, a1, a0
465 ; RV32IM-NEXT:    mv a0, a2
466 ; RV32IM-NEXT:    ret
468 ; RV64IM-LABEL: subi_i64:
469 ; RV64IM:       # %bb.0: # %entry
470 ; RV64IM-NEXT:    lui a1, 301
471 ; RV64IM-NEXT:    addiw a1, a1, 1548
472 ; RV64IM-NEXT:    sub a0, a0, a1
473 ; RV64IM-NEXT:    ret
474 entry:
475   %0 = sub i64 %a, 1234444
476   ret i64 %0
479 define i64 @neg_i64(i64 %a) {
480 ; RV32IM-LABEL: neg_i64:
481 ; RV32IM:       # %bb.0: # %entry
482 ; RV32IM-NEXT:    neg a2, a0
483 ; RV32IM-NEXT:    snez a0, a0
484 ; RV32IM-NEXT:    neg a1, a1
485 ; RV32IM-NEXT:    sub a1, a1, a0
486 ; RV32IM-NEXT:    mv a0, a2
487 ; RV32IM-NEXT:    ret
489 ; RV64IM-LABEL: neg_i64:
490 ; RV64IM:       # %bb.0: # %entry
491 ; RV64IM-NEXT:    neg a0, a0
492 ; RV64IM-NEXT:    ret
493 entry:
494   %0 = sub i64 0, %a
495   ret i64 %0
498 ; TODO: Handle G_SELECT, which is needed to have i64 shifts working on RV32.
500 define i64 @and_i64(i64 %a, i64 %b) {
501 ; RV32IM-LABEL: and_i64:
502 ; RV32IM:       # %bb.0: # %entry
503 ; RV32IM-NEXT:    and a0, a0, a2
504 ; RV32IM-NEXT:    and a1, a1, a3
505 ; RV32IM-NEXT:    ret
507 ; RV64IM-LABEL: and_i64:
508 ; RV64IM:       # %bb.0: # %entry
509 ; RV64IM-NEXT:    and a0, a0, a1
510 ; RV64IM-NEXT:    ret
511 entry:
512   %0 = and i64 %a, %b
513   ret i64 %0
516 define i64 @andi_i64(i64 %a) {
517 ; RV32IM-LABEL: andi_i64:
518 ; RV32IM:       # %bb.0: # %entry
519 ; RV32IM-NEXT:    andi a0, a0, 1234
520 ; RV32IM-NEXT:    li a1, 0
521 ; RV32IM-NEXT:    ret
523 ; RV64IM-LABEL: andi_i64:
524 ; RV64IM:       # %bb.0: # %entry
525 ; RV64IM-NEXT:    andi a0, a0, 1234
526 ; RV64IM-NEXT:    ret
527 entry:
528   %0 = and i64 %a, 1234
529   ret i64 %0
532 define i64 @or_i64(i64 %a, i64 %b) {
533 ; RV32IM-LABEL: or_i64:
534 ; RV32IM:       # %bb.0: # %entry
535 ; RV32IM-NEXT:    or a0, a0, a2
536 ; RV32IM-NEXT:    or a1, a1, a3
537 ; RV32IM-NEXT:    ret
539 ; RV64IM-LABEL: or_i64:
540 ; RV64IM:       # %bb.0: # %entry
541 ; RV64IM-NEXT:    or a0, a0, a1
542 ; RV64IM-NEXT:    ret
543 entry:
544   %0 = or i64 %a, %b
545   ret i64 %0
548 define i64 @ori_i64(i64 %a) {
549 ; RV32IM-LABEL: ori_i64:
550 ; RV32IM:       # %bb.0: # %entry
551 ; RV32IM-NEXT:    ori a0, a0, 1234
552 ; RV32IM-NEXT:    ret
554 ; RV64IM-LABEL: ori_i64:
555 ; RV64IM:       # %bb.0: # %entry
556 ; RV64IM-NEXT:    ori a0, a0, 1234
557 ; RV64IM-NEXT:    ret
558 entry:
559   %0 = or i64 %a, 1234
560   ret i64 %0
563 define i64 @xor_i64(i64 %a, i64 %b) {
564 ; RV32IM-LABEL: xor_i64:
565 ; RV32IM:       # %bb.0: # %entry
566 ; RV32IM-NEXT:    xor a0, a0, a2
567 ; RV32IM-NEXT:    xor a1, a1, a3
568 ; RV32IM-NEXT:    ret
570 ; RV64IM-LABEL: xor_i64:
571 ; RV64IM:       # %bb.0: # %entry
572 ; RV64IM-NEXT:    xor a0, a0, a1
573 ; RV64IM-NEXT:    ret
574 entry:
575   %0 = xor i64 %a, %b
576   ret i64 %0
579 define i64 @xori_i64(i64 %a) {
580 ; RV32IM-LABEL: xori_i64:
581 ; RV32IM:       # %bb.0: # %entry
582 ; RV32IM-NEXT:    xori a0, a0, 1234
583 ; RV32IM-NEXT:    ret
585 ; RV64IM-LABEL: xori_i64:
586 ; RV64IM:       # %bb.0: # %entry
587 ; RV64IM-NEXT:    xori a0, a0, 1234
588 ; RV64IM-NEXT:    ret
589 entry:
590   %0 = xor i64 %a, 1234
591   ret i64 %0
594 define i64 @mul_i64(i64 %a, i64 %b) {
595 ; RV32IM-LABEL: mul_i64:
596 ; RV32IM:       # %bb.0: # %entry
597 ; RV32IM-NEXT:    mul a4, a0, a2
598 ; RV32IM-NEXT:    mul a1, a1, a2
599 ; RV32IM-NEXT:    mul a3, a0, a3
600 ; RV32IM-NEXT:    mulhu a0, a0, a2
601 ; RV32IM-NEXT:    add a1, a1, a3
602 ; RV32IM-NEXT:    add a1, a1, a0
603 ; RV32IM-NEXT:    mv a0, a4
604 ; RV32IM-NEXT:    ret
606 ; RV64IM-LABEL: mul_i64:
607 ; RV64IM:       # %bb.0: # %entry
608 ; RV64IM-NEXT:    mul a0, a0, a1
609 ; RV64IM-NEXT:    ret
610 entry:
611   %0 = mul i64 %a, %b
612   ret i64 %0
615 ; TODO: Handle G_SDIV, G_SREM, G_UDIV, G_UREM for i64 on RV32. Likely will be
616 ; dispatched to a libcall?