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:
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
28 define { i256, i8 } @u256_checked_add(i256 %x, i256 %y) {
29 ; CHECK-LABEL: u256_checked_add:
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
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
43 %6 = insertvalue { i256, i8 } undef, i256 %2, 0
44 %7 = insertvalue { i256, i8 } %6, i8 %5, 1
48 define { i256, i8 } @u256_overflowing_add(i256 %x, i256 %y) {
49 ; CHECK-LABEL: u256_overflowing_add:
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
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
61 %5 = insertvalue { i256, i8 } undef, i256 %2, 0
62 %6 = insertvalue { i256, i8 } %5, i8 %4, 1
66 define i256 @u256_saturating_add(i256 %x, i256 %y) {
67 ; CHECK-LABEL: u256_saturating_add:
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
78 %1 = tail call i256 @llvm.uadd.sat.i256(i256 %x, i256 %y)
82 define i256 @u256_sub(i256 %x, i256 %y) {
83 ; CHECK-LABEL: u256_sub:
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
94 define { i256, i8 } @u256_checked_sub(i256 %x, i256 %y) {
95 ; CHECK-LABEL: u256_checked_sub:
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
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
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
114 define { i256, i8 } @u256_overflowing_sub(i256 %x, i256 %y) {
115 ; CHECK-LABEL: u256_overflowing_sub:
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
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
132 define i256 @u256_saturating_sub(i256 %x, i256 %y) {
133 ; CHECK-LABEL: u256_saturating_sub:
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
144 %1 = tail call i256 @llvm.usub.sat.i256(i256 %x, i256 %y)
148 define i256 @i256_add(i256 %x, i256 %y) {
149 ; CHECK-LABEL: i256_add:
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
160 define { i256, i8 } @i256_checked_add(i256 %x, i256 %y) {
161 ; CHECK-LABEL: i256_checked_add:
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
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
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
180 define { i256, i8 } @i256_overflowing_add(i256 %x, i256 %y) {
181 ; CHECK-LABEL: i256_overflowing_add:
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
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
198 define i256 @i256_saturating_add(i256 %x, i256 %y) {
199 ; CHECK-LABEL: i256_saturating_add:
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
212 %1 = tail call i256 @llvm.sadd.sat.i256(i256 %x, i256 %y)
216 define i256 @i256_sub(i256 %x, i256 %y) {
217 ; CHECK-LABEL: i256_sub:
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
228 define { i256, i8 } @i256_checked_sub(i256 %x, i256 %y) {
229 ; CHECK-LABEL: i256_checked_sub:
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
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
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
248 define { i256, i8 } @i256_overflowing_sub(i256 %x, i256 %y) {
249 ; CHECK-LABEL: i256_overflowing_sub:
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
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
266 define i256 @i256_saturating_sub(i256 %x, i256 %y) {
267 ; CHECK-LABEL: i256_saturating_sub:
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
280 %1 = tail call i256 @llvm.ssub.sat.i256(i256 %x, i256 %y)