[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / i256-math.ll
blobc275337389c7e5dc6b513a362bb711ef11539843
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 declare { i256, i1 } @llvm.uadd.with.overflow.i256(i256, i256)
5 declare   i256       @llvm.uadd.sat.i256(i256, i256)
7 declare { i256, i1 } @llvm.usub.with.overflow.i256(i256, i256)
8 declare   i256       @llvm.usub.sat.i256(i256, i256)
10 declare { i256, i1 } @llvm.sadd.with.overflow.i256(i256, i256)
11 declare   i256       @llvm.sadd.sat.i256(i256, i256)
13 declare { i256, i1 } @llvm.ssub.with.overflow.i256(i256, i256)
14 declare   i256       @llvm.ssub.sat.i256(i256, i256)
16 define i256 @u256_add(i256 %x, i256 %y) {
17 ; CHECK-LABEL: u256_add:
18 ; CHECK:       // %bb.0:
19 ; CHECK-NEXT:    adds x0, x0, x4
20 ; CHECK-NEXT:    adcs x1, x1, x5
21 ; CHECK-NEXT:    adcs x2, x2, x6
22 ; CHECK-NEXT:    adc x3, x3, x7
23 ; CHECK-NEXT:    ret
24   %1 = add i256 %x, %y
25   ret i256 %1
28 define { i256, i8 } @u256_checked_add(i256 %x, i256 %y) {
29 ; CHECK-LABEL: u256_checked_add:
30 ; CHECK:       // %bb.0:
31 ; CHECK-NEXT:    adds x0, x0, x4
32 ; CHECK-NEXT:    adcs x1, x1, x5
33 ; CHECK-NEXT:    adcs x2, x2, x6
34 ; CHECK-NEXT:    adcs x3, x3, x7
35 ; CHECK-NEXT:    cset w8, hs
36 ; CHECK-NEXT:    eor w4, w8, #0x1
37 ; CHECK-NEXT:    ret
38   %1 = tail call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
39   %2 = extractvalue { i256, i1 } %1, 0
40   %3 = extractvalue { i256, i1 } %1, 1
41   %4 = xor i1 %3, true
42   %5 = zext i1 %4 to i8
43   %6 = insertvalue { i256, i8 } undef, i256 %2, 0
44   %7 = insertvalue { i256, i8 } %6, i8 %5, 1
45   ret { i256, i8 } %7
48 define { i256, i8 } @u256_overflowing_add(i256 %x, i256 %y) {
49 ; CHECK-LABEL: u256_overflowing_add:
50 ; CHECK:       // %bb.0:
51 ; CHECK-NEXT:    adds x0, x0, x4
52 ; CHECK-NEXT:    adcs x1, x1, x5
53 ; CHECK-NEXT:    adcs x2, x2, x6
54 ; CHECK-NEXT:    adcs x3, x3, x7
55 ; CHECK-NEXT:    cset w4, hs
56 ; CHECK-NEXT:    ret
57   %1 = tail call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
58   %2 = extractvalue { i256, i1 } %1, 0
59   %3 = extractvalue { i256, i1 } %1, 1
60   %4 = zext i1 %3 to i8
61   %5 = insertvalue { i256, i8 } undef, i256 %2, 0
62   %6 = insertvalue { i256, i8 } %5, i8 %4, 1
63   ret { i256, i8 } %6
66 define i256 @u256_saturating_add(i256 %x, i256 %y) {
67 ; CHECK-LABEL: u256_saturating_add:
68 ; CHECK:       // %bb.0:
69 ; CHECK-NEXT:    adds x8, x0, x4
70 ; CHECK-NEXT:    adcs x9, x1, x5
71 ; CHECK-NEXT:    adcs x10, x2, x6
72 ; CHECK-NEXT:    adcs x11, x3, x7
73 ; CHECK-NEXT:    csinv x0, x8, xzr, lo
74 ; CHECK-NEXT:    csinv x1, x9, xzr, lo
75 ; CHECK-NEXT:    csinv x2, x10, xzr, lo
76 ; CHECK-NEXT:    csinv x3, x11, xzr, lo
77 ; CHECK-NEXT:    ret
78   %1 = tail call i256 @llvm.uadd.sat.i256(i256 %x, i256 %y)
79   ret i256 %1
82 define i256 @u256_sub(i256 %x, i256 %y) {
83 ; CHECK-LABEL: u256_sub:
84 ; CHECK:       // %bb.0:
85 ; CHECK-NEXT:    subs x0, x0, x4
86 ; CHECK-NEXT:    sbcs x1, x1, x5
87 ; CHECK-NEXT:    sbcs x2, x2, x6
88 ; CHECK-NEXT:    sbc x3, x3, x7
89 ; CHECK-NEXT:    ret
90   %1 = sub i256 %x, %y
91   ret i256 %1
94 define { i256, i8 } @u256_checked_sub(i256 %x, i256 %y) {
95 ; CHECK-LABEL: u256_checked_sub:
96 ; CHECK:       // %bb.0:
97 ; CHECK-NEXT:    subs x0, x0, x4
98 ; CHECK-NEXT:    sbcs x1, x1, x5
99 ; CHECK-NEXT:    sbcs x2, x2, x6
100 ; CHECK-NEXT:    sbcs x3, x3, x7
101 ; CHECK-NEXT:    cset w8, lo
102 ; CHECK-NEXT:    eor w4, w8, #0x1
103 ; CHECK-NEXT:    ret
104   %1 = tail call { i256, i1 } @llvm.usub.with.overflow.i256(i256 %x, i256 %y)
105   %2 = extractvalue { i256, i1 } %1, 0
106   %3 = extractvalue { i256, i1 } %1, 1
107   %4 = xor i1 %3, true
108   %5 = zext i1 %4 to i8
109   %6 = insertvalue { i256, i8 } undef, i256 %2, 0
110   %7 = insertvalue { i256, i8 } %6, i8 %5, 1
111   ret { i256, i8 } %7
114 define { i256, i8 } @u256_overflowing_sub(i256 %x, i256 %y) {
115 ; CHECK-LABEL: u256_overflowing_sub:
116 ; CHECK:       // %bb.0:
117 ; CHECK-NEXT:    subs x0, x0, x4
118 ; CHECK-NEXT:    sbcs x1, x1, x5
119 ; CHECK-NEXT:    sbcs x2, x2, x6
120 ; CHECK-NEXT:    sbcs x3, x3, x7
121 ; CHECK-NEXT:    cset w4, lo
122 ; CHECK-NEXT:    ret
123   %1 = tail call { i256, i1 } @llvm.usub.with.overflow.i256(i256 %x, i256 %y)
124   %2 = extractvalue { i256, i1 } %1, 0
125   %3 = extractvalue { i256, i1 } %1, 1
126   %4 = zext i1 %3 to i8
127   %5 = insertvalue { i256, i8 } undef, i256 %2, 0
128   %6 = insertvalue { i256, i8 } %5, i8 %4, 1
129   ret { i256, i8 } %6
132 define i256 @u256_saturating_sub(i256 %x, i256 %y) {
133 ; CHECK-LABEL: u256_saturating_sub:
134 ; CHECK:       // %bb.0:
135 ; CHECK-NEXT:    subs x8, x0, x4
136 ; CHECK-NEXT:    sbcs x9, x1, x5
137 ; CHECK-NEXT:    sbcs x10, x2, x6
138 ; CHECK-NEXT:    sbcs x11, x3, x7
139 ; CHECK-NEXT:    csel x0, xzr, x8, lo
140 ; CHECK-NEXT:    csel x1, xzr, x9, lo
141 ; CHECK-NEXT:    csel x2, xzr, x10, lo
142 ; CHECK-NEXT:    csel x3, xzr, x11, lo
143 ; CHECK-NEXT:    ret
144   %1 = tail call i256 @llvm.usub.sat.i256(i256 %x, i256 %y)
145   ret i256 %1
148 define i256 @i256_add(i256 %x, i256 %y) {
149 ; CHECK-LABEL: i256_add:
150 ; CHECK:       // %bb.0:
151 ; CHECK-NEXT:    adds x0, x0, x4
152 ; CHECK-NEXT:    adcs x1, x1, x5
153 ; CHECK-NEXT:    adcs x2, x2, x6
154 ; CHECK-NEXT:    adc x3, x3, x7
155 ; CHECK-NEXT:    ret
156   %1 = add i256 %x, %y
157   ret i256 %1
160 define { i256, i8 } @i256_checked_add(i256 %x, i256 %y) {
161 ; CHECK-LABEL: i256_checked_add:
162 ; CHECK:       // %bb.0:
163 ; CHECK-NEXT:    adds x0, x0, x4
164 ; CHECK-NEXT:    adcs x1, x1, x5
165 ; CHECK-NEXT:    adcs x2, x2, x6
166 ; CHECK-NEXT:    adcs x3, x3, x7
167 ; CHECK-NEXT:    cset w8, vs
168 ; CHECK-NEXT:    eor w4, w8, #0x1
169 ; CHECK-NEXT:    ret
170   %1 = tail call { i256, i1 } @llvm.sadd.with.overflow.i256(i256 %x, i256 %y)
171   %2 = extractvalue { i256, i1 } %1, 0
172   %3 = extractvalue { i256, i1 } %1, 1
173   %4 = xor i1 %3, true
174   %5 = zext i1 %4 to i8
175   %6 = insertvalue { i256, i8 } undef, i256 %2, 0
176   %7 = insertvalue { i256, i8 } %6, i8 %5, 1
177   ret { i256, i8 } %7
180 define { i256, i8 } @i256_overflowing_add(i256 %x, i256 %y) {
181 ; CHECK-LABEL: i256_overflowing_add:
182 ; CHECK:       // %bb.0:
183 ; CHECK-NEXT:    adds x0, x0, x4
184 ; CHECK-NEXT:    adcs x1, x1, x5
185 ; CHECK-NEXT:    adcs x2, x2, x6
186 ; CHECK-NEXT:    adcs x3, x3, x7
187 ; CHECK-NEXT:    cset w4, vs
188 ; CHECK-NEXT:    ret
189   %1 = tail call { i256, i1 } @llvm.sadd.with.overflow.i256(i256 %x, i256 %y)
190   %2 = extractvalue { i256, i1 } %1, 0
191   %3 = extractvalue { i256, i1 } %1, 1
192   %4 = zext i1 %3 to i8
193   %5 = insertvalue { i256, i8 } undef, i256 %2, 0
194   %6 = insertvalue { i256, i8 } %5, i8 %4, 1
195   ret { i256, i8 } %6
198 define i256 @i256_saturating_add(i256 %x, i256 %y) {
199 ; CHECK-LABEL: i256_saturating_add:
200 ; CHECK:       // %bb.0:
201 ; CHECK-NEXT:    adds x8, x0, x4
202 ; CHECK-NEXT:    adcs x9, x1, x5
203 ; CHECK-NEXT:    adcs x10, x2, x6
204 ; CHECK-NEXT:    adcs x11, x3, x7
205 ; CHECK-NEXT:    asr x12, x11, #63
206 ; CHECK-NEXT:    csel x0, x12, x8, vs
207 ; CHECK-NEXT:    eor x8, x12, #0x8000000000000000
208 ; CHECK-NEXT:    csel x1, x12, x9, vs
209 ; CHECK-NEXT:    csel x2, x12, x10, vs
210 ; CHECK-NEXT:    csel x3, x8, x11, vs
211 ; CHECK-NEXT:    ret
212   %1 = tail call i256 @llvm.sadd.sat.i256(i256 %x, i256 %y)
213   ret i256 %1
216 define i256 @i256_sub(i256 %x, i256 %y) {
217 ; CHECK-LABEL: i256_sub:
218 ; CHECK:       // %bb.0:
219 ; CHECK-NEXT:    subs x0, x0, x4
220 ; CHECK-NEXT:    sbcs x1, x1, x5
221 ; CHECK-NEXT:    sbcs x2, x2, x6
222 ; CHECK-NEXT:    sbc x3, x3, x7
223 ; CHECK-NEXT:    ret
224   %1 = sub i256 %x, %y
225   ret i256 %1
228 define { i256, i8 } @i256_checked_sub(i256 %x, i256 %y) {
229 ; CHECK-LABEL: i256_checked_sub:
230 ; CHECK:       // %bb.0:
231 ; CHECK-NEXT:    subs x0, x0, x4
232 ; CHECK-NEXT:    sbcs x1, x1, x5
233 ; CHECK-NEXT:    sbcs x2, x2, x6
234 ; CHECK-NEXT:    sbcs x3, x3, x7
235 ; CHECK-NEXT:    cset w8, vs
236 ; CHECK-NEXT:    eor w4, w8, #0x1
237 ; CHECK-NEXT:    ret
238   %1 = tail call { i256, i1 } @llvm.ssub.with.overflow.i256(i256 %x, i256 %y)
239   %2 = extractvalue { i256, i1 } %1, 0
240   %3 = extractvalue { i256, i1 } %1, 1
241   %4 = xor i1 %3, true
242   %5 = zext i1 %4 to i8
243   %6 = insertvalue { i256, i8 } undef, i256 %2, 0
244   %7 = insertvalue { i256, i8 } %6, i8 %5, 1
245   ret { i256, i8 } %7
248 define { i256, i8 } @i256_overflowing_sub(i256 %x, i256 %y) {
249 ; CHECK-LABEL: i256_overflowing_sub:
250 ; CHECK:       // %bb.0:
251 ; CHECK-NEXT:    subs x0, x0, x4
252 ; CHECK-NEXT:    sbcs x1, x1, x5
253 ; CHECK-NEXT:    sbcs x2, x2, x6
254 ; CHECK-NEXT:    sbcs x3, x3, x7
255 ; CHECK-NEXT:    cset w4, vs
256 ; CHECK-NEXT:    ret
257   %1 = tail call { i256, i1 } @llvm.ssub.with.overflow.i256(i256 %x, i256 %y)
258   %2 = extractvalue { i256, i1 } %1, 0
259   %3 = extractvalue { i256, i1 } %1, 1
260   %4 = zext i1 %3 to i8
261   %5 = insertvalue { i256, i8 } undef, i256 %2, 0
262   %6 = insertvalue { i256, i8 } %5, i8 %4, 1
263   ret { i256, i8 } %6
266 define i256 @i256_saturating_sub(i256 %x, i256 %y) {
267 ; CHECK-LABEL: i256_saturating_sub:
268 ; CHECK:       // %bb.0:
269 ; CHECK-NEXT:    subs x8, x0, x4
270 ; CHECK-NEXT:    sbcs x9, x1, x5
271 ; CHECK-NEXT:    sbcs x10, x2, x6
272 ; CHECK-NEXT:    sbcs x11, x3, x7
273 ; CHECK-NEXT:    asr x12, x11, #63
274 ; CHECK-NEXT:    csel x0, x12, x8, vs
275 ; CHECK-NEXT:    eor x8, x12, #0x8000000000000000
276 ; CHECK-NEXT:    csel x1, x12, x9, vs
277 ; CHECK-NEXT:    csel x2, x12, x10, vs
278 ; CHECK-NEXT:    csel x3, x8, x11, vs
279 ; CHECK-NEXT:    ret
280   %1 = tail call i256 @llvm.ssub.sat.i256(i256 %x, i256 %y)
281   ret i256 %1