1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=riscv32 -mattr=+m | FileCheck %s --check-prefixes=RISCV32
define { i128, i8 } @muloti_test(i128 %l, i128 %r) #0 {
; RISCV32-LABEL: muloti_test:
; RISCV32: # %bb.0: # %start
; RISCV32-NEXT: addi sp, sp, -96
; RISCV32-NEXT: sw ra, 92(sp)
; RISCV32-NEXT: sw s0, 88(sp)
; RISCV32-NEXT: sw s1, 84(sp)
; RISCV32-NEXT: sw s2, 80(sp)
; RISCV32-NEXT: sw s3, 76(sp)
; RISCV32-NEXT: sw s4, 72(sp)
; RISCV32-NEXT: sw s5, 68(sp)
; RISCV32-NEXT: sw s6, 64(sp)
; RISCV32-NEXT: sw s7, 60(sp)
; RISCV32-NEXT: sw s8, 56(sp)
; RISCV32-NEXT: lw s2, 12(a1)
; RISCV32-NEXT: lw s6, 8(a1)
; RISCV32-NEXT: lw s3, 12(a2)
; RISCV32-NEXT: lw s7, 8(a2)
; RISCV32-NEXT: lw s0, 0(a1)
; RISCV32-NEXT: lw s8, 4(a1)
; RISCV32-NEXT: lw s1, 0(a2)
; RISCV32-NEXT: lw s5, 4(a2)
; RISCV32-NEXT: mv s4, a0
; RISCV32-NEXT: sw zero, 20(sp)
; RISCV32-NEXT: sw zero, 16(sp)
; RISCV32-NEXT: sw zero, 36(sp)
; RISCV32-NEXT: sw zero, 32(sp)
; RISCV32-NEXT: sw s5, 12(sp)
; RISCV32-NEXT: sw s1, 8(sp)
; RISCV32-NEXT: sw s8, 28(sp)
; RISCV32-NEXT: addi a0, sp, 40
; RISCV32-NEXT: addi a1, sp, 24
; RISCV32-NEXT: addi a2, sp, 8
; RISCV32-NEXT: sw s0, 24(sp)
; RISCV32-NEXT: call __multi3
; RISCV32-NEXT: mul a0, s8, s7
; RISCV32-NEXT: mul a1, s3, s0
; RISCV32-NEXT: add a0, a1, a0
; RISCV32-NEXT: mulhu a5, s7, s0
; RISCV32-NEXT: add a0, a5, a0
; RISCV32-NEXT: mul a1, s5, s6
; RISCV32-NEXT: mul a2, s2, s1
; RISCV32-NEXT: add a1, a2, a1
; RISCV32-NEXT: mulhu t0, s6, s1
; RISCV32-NEXT: add t1, t0, a1
; RISCV32-NEXT: add a6, t1, a0
; RISCV32-NEXT: mul a1, s7, s0
; RISCV32-NEXT: mul a3, s6, s1
; RISCV32-NEXT: add a4, a3, a1
; RISCV32-NEXT: lw a1, 52(sp)
; RISCV32-NEXT: lw a2, 48(sp)
; RISCV32-NEXT: sltu a3, a4, a3
; RISCV32-NEXT: add a3, a6, a3
; RISCV32-NEXT: add a3, a1, a3
; RISCV32-NEXT: add a6, a2, a4
; RISCV32-NEXT: sltu a2, a6, a2
; RISCV32-NEXT: add a7, a3, a2
; RISCV32-NEXT: beq a7, a1, .LBB0_2
; RISCV32-NEXT: # %bb.1: # %start
; RISCV32-NEXT: sltu a2, a7, a1
; RISCV32-NEXT: .LBB0_2: # %start
; RISCV32-NEXT: sltu a0, a0, a5
; RISCV32-NEXT: snez a1, s8
; RISCV32-NEXT: snez a3, s3
; RISCV32-NEXT: and a1, a3, a1
; RISCV32-NEXT: mulhu a3, s3, s0
; RISCV32-NEXT: snez a3, a3
; RISCV32-NEXT: or a1, a1, a3
; RISCV32-NEXT: mulhu a3, s8, s7
; RISCV32-NEXT: snez a3, a3
; RISCV32-NEXT: or a1, a1, a3
; RISCV32-NEXT: or a0, a1, a0
; RISCV32-NEXT: sltu a1, t1, t0
; RISCV32-NEXT: snez a3, s5
; RISCV32-NEXT: snez a4, s2
; RISCV32-NEXT: and a3, a4, a3
; RISCV32-NEXT: mulhu a4, s2, s1
; RISCV32-NEXT: snez a4, a4
; RISCV32-NEXT: or a3, a3, a4
; RISCV32-NEXT: mulhu a4, s5, s6
; RISCV32-NEXT: snez a4, a4
; RISCV32-NEXT: or a3, a3, a4
; RISCV32-NEXT: or a1, a3, a1
; RISCV32-NEXT: or a3, s7, s3
; RISCV32-NEXT: snez a3, a3
; RISCV32-NEXT: or a4, s6, s2
; RISCV32-NEXT: snez a4, a4
; RISCV32-NEXT: and a3, a4, a3
; RISCV32-NEXT: or a1, a3, a1
; RISCV32-NEXT: or a0, a1, a0
; RISCV32-NEXT: lw a1, 44(sp)
; RISCV32-NEXT: lw a3, 40(sp)
; RISCV32-NEXT: or a0, a0, a2
; RISCV32-NEXT: andi a0, a0, 1
; RISCV32-NEXT: sw a1, 4(s4)
; RISCV32-NEXT: sw a3, 0(s4)
; RISCV32-NEXT: sw a6, 8(s4)
; RISCV32-NEXT: sw a7, 12(s4)
; RISCV32-NEXT: sb a0, 16(s4)
; RISCV32-NEXT: lw s8, 56(sp)
; RISCV32-NEXT: lw s7, 60(sp)
; RISCV32-NEXT: lw s6, 64(sp)
; RISCV32-NEXT: lw s5, 68(sp)
; RISCV32-NEXT: lw s4, 72(sp)
; RISCV32-NEXT: lw s3, 76(sp)
; RISCV32-NEXT: lw s2, 80(sp)
; RISCV32-NEXT: lw s1, 84(sp)
; RISCV32-NEXT: lw s0, 88(sp)
; RISCV32-NEXT: lw ra, 92(sp)
; RISCV32-NEXT: addi sp, sp, 96
; RISCV32-NEXT: ret
start:
%0 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %l, i128 %r) #2
%1 = extractvalue { i128, i1 } %0, 0
%2 = extractvalue { i128, i1 } %0, 1
%3 = zext i1 %2 to i8
%4 = insertvalue { i128, i8 } undef, i128 %1, 0
%5 = insertvalue { i128, i8 } %4, i8 %3, 1
ret { i128, i8 } %5
}
; Function Attrs: nounwind readnone speculatable
declare { i128, i1 } @llvm.umul.with.overflow.i128(i128, i128) #1
attributes #0 = { nounwind readnone }
attributes #1 = { nounwind readnone speculatable }
attributes #2 = { nounwind }
|