1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 define i32 @uadd(i32 %x, i32 %y) {
6 ; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
7 ; CHECK-NEXT: ret i32 [[S]]
9 %ao = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
10 %o = extractvalue { i32, i1 } %ao, 1
11 %a = extractvalue { i32, i1 } %ao, 0
12 %s = select i1 %o, i32 -1, i32 %a
16 define i32 @usub(i32 %x, i32 %y) {
18 ; CHECK-NEXT: [[S:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
19 ; CHECK-NEXT: ret i32 [[S]]
21 %ao = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
22 %o = extractvalue { i32, i1 } %ao, 1
23 %a = extractvalue { i32, i1 } %ao, 0
24 %s = select i1 %o, i32 0, i32 %a
29 define i8 @sadd_x_lt_min(i8 %x, i8 %y) {
30 ; CHECK-LABEL: @sadd_x_lt_min(
31 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
32 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
33 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
34 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 0
35 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
36 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
37 ; CHECK-NEXT: ret i8 [[R]]
39 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
40 %o = extractvalue { i8, i1 } %ao, 1
41 %a = extractvalue { i8, i1 } %ao, 0
42 %c = icmp slt i8 %x, 0
43 %s = select i1 %c, i8 127, i8 -128
44 %r = select i1 %o, i8 %s, i8 %a
48 define i8 @sadd_x_lt_max(i8 %x, i8 %y) {
49 ; CHECK-LABEL: @sadd_x_lt_max(
50 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
51 ; CHECK-NEXT: ret i8 [[R]]
53 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
54 %o = extractvalue { i8, i1 } %ao, 1
55 %a = extractvalue { i8, i1 } %ao, 0
56 %c = icmp slt i8 %x, 0
57 %s = select i1 %c, i8 -128, i8 127
58 %r = select i1 %o, i8 %s, i8 %a
62 define i8 @sadd_x_le_min(i8 %x, i8 %y) {
63 ; CHECK-LABEL: @sadd_x_le_min(
64 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
65 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
66 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
67 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1
68 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
69 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
70 ; CHECK-NEXT: ret i8 [[R]]
72 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
73 %o = extractvalue { i8, i1 } %ao, 1
74 %a = extractvalue { i8, i1 } %ao, 0
75 %c = icmp sle i8 %x, 0
76 %s = select i1 %c, i8 127, i8 -128
77 %r = select i1 %o, i8 %s, i8 %a
81 define i8 @sadd_x_le_max(i8 %x, i8 %y) {
82 ; CHECK-LABEL: @sadd_x_le_max(
83 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
84 ; CHECK-NEXT: ret i8 [[R]]
86 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
87 %o = extractvalue { i8, i1 } %ao, 1
88 %a = extractvalue { i8, i1 } %ao, 0
89 %c = icmp sle i8 %x, 0
90 %s = select i1 %c, i8 -128, i8 127
91 %r = select i1 %o, i8 %s, i8 %a
95 define i8 @sadd_x_gt_min(i8 %x, i8 %y) {
96 ; CHECK-LABEL: @sadd_x_gt_min(
97 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
98 ; CHECK-NEXT: ret i8 [[R]]
100 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
101 %o = extractvalue { i8, i1 } %ao, 1
102 %a = extractvalue { i8, i1 } %ao, 0
103 %c = icmp sgt i8 %x, 0
104 %s = select i1 %c, i8 127, i8 -128
105 %r = select i1 %o, i8 %s, i8 %a
109 define i8 @sadd_x_gt_max(i8 %x, i8 %y) {
110 ; CHECK-LABEL: @sadd_x_gt_max(
111 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
112 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
113 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
114 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0
115 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
116 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
117 ; CHECK-NEXT: ret i8 [[R]]
119 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
120 %o = extractvalue { i8, i1 } %ao, 1
121 %a = extractvalue { i8, i1 } %ao, 0
122 %c = icmp sgt i8 %x, 0
123 %s = select i1 %c, i8 -128, i8 127
124 %r = select i1 %o, i8 %s, i8 %a
128 define i8 @sadd_x_ge_min(i8 %x, i8 %y) {
129 ; CHECK-LABEL: @sadd_x_ge_min(
130 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
131 ; CHECK-NEXT: ret i8 [[R]]
133 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
134 %o = extractvalue { i8, i1 } %ao, 1
135 %a = extractvalue { i8, i1 } %ao, 0
136 %c = icmp sge i8 %x, 0
137 %s = select i1 %c, i8 127, i8 -128
138 %r = select i1 %o, i8 %s, i8 %a
142 define i8 @sadd_x_ge_max(i8 %x, i8 %y) {
143 ; CHECK-LABEL: @sadd_x_ge_max(
144 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
145 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
146 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
147 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -1
148 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
149 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
150 ; CHECK-NEXT: ret i8 [[R]]
152 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
153 %o = extractvalue { i8, i1 } %ao, 1
154 %a = extractvalue { i8, i1 } %ao, 0
155 %c = icmp sge i8 %x, 0
156 %s = select i1 %c, i8 -128, i8 127
157 %r = select i1 %o, i8 %s, i8 %a
162 define i8 @sadd_y_lt_min(i8 %x, i8 %y) {
163 ; CHECK-LABEL: @sadd_y_lt_min(
164 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
165 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
166 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
167 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 0
168 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
169 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
170 ; CHECK-NEXT: ret i8 [[R]]
172 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
173 %o = extractvalue { i8, i1 } %ao, 1
174 %a = extractvalue { i8, i1 } %ao, 0
175 %c = icmp slt i8 %y, 0
176 %s = select i1 %c, i8 127, i8 -128
177 %r = select i1 %o, i8 %s, i8 %a
181 define i8 @sadd_y_lt_max(i8 %x, i8 %y) {
182 ; CHECK-LABEL: @sadd_y_lt_max(
183 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
184 ; CHECK-NEXT: ret i8 [[R]]
186 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
187 %o = extractvalue { i8, i1 } %ao, 1
188 %a = extractvalue { i8, i1 } %ao, 0
189 %c = icmp slt i8 %y, 0
190 %s = select i1 %c, i8 -128, i8 127
191 %r = select i1 %o, i8 %s, i8 %a
195 define i8 @sadd_y_le_min(i8 %x, i8 %y) {
196 ; CHECK-LABEL: @sadd_y_le_min(
197 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
198 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
199 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
200 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 1
201 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
202 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
203 ; CHECK-NEXT: ret i8 [[R]]
205 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
206 %o = extractvalue { i8, i1 } %ao, 1
207 %a = extractvalue { i8, i1 } %ao, 0
208 %c = icmp sle i8 %y, 0
209 %s = select i1 %c, i8 127, i8 -128
210 %r = select i1 %o, i8 %s, i8 %a
214 define i8 @sadd_y_le_max(i8 %x, i8 %y) {
215 ; CHECK-LABEL: @sadd_y_le_max(
216 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
217 ; CHECK-NEXT: ret i8 [[R]]
219 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
220 %o = extractvalue { i8, i1 } %ao, 1
221 %a = extractvalue { i8, i1 } %ao, 0
222 %c = icmp sle i8 %y, 0
223 %s = select i1 %c, i8 -128, i8 127
224 %r = select i1 %o, i8 %s, i8 %a
228 define i8 @sadd_y_gt_min(i8 %x, i8 %y) {
229 ; CHECK-LABEL: @sadd_y_gt_min(
230 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
231 ; CHECK-NEXT: ret i8 [[R]]
233 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
234 %o = extractvalue { i8, i1 } %ao, 1
235 %a = extractvalue { i8, i1 } %ao, 0
236 %c = icmp sgt i8 %y, 0
237 %s = select i1 %c, i8 127, i8 -128
238 %r = select i1 %o, i8 %s, i8 %a
242 define i8 @sadd_y_gt_max(i8 %x, i8 %y) {
243 ; CHECK-LABEL: @sadd_y_gt_max(
244 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
245 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
246 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
247 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], 0
248 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
249 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
250 ; CHECK-NEXT: ret i8 [[R]]
252 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
253 %o = extractvalue { i8, i1 } %ao, 1
254 %a = extractvalue { i8, i1 } %ao, 0
255 %c = icmp sgt i8 %y, 0
256 %s = select i1 %c, i8 -128, i8 127
257 %r = select i1 %o, i8 %s, i8 %a
261 define i8 @sadd_y_ge_min(i8 %x, i8 %y) {
262 ; CHECK-LABEL: @sadd_y_ge_min(
263 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
264 ; CHECK-NEXT: ret i8 [[R]]
266 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
267 %o = extractvalue { i8, i1 } %ao, 1
268 %a = extractvalue { i8, i1 } %ao, 0
269 %c = icmp sge i8 %y, 0
270 %s = select i1 %c, i8 127, i8 -128
271 %r = select i1 %o, i8 %s, i8 %a
275 define i8 @sadd_y_ge_max(i8 %x, i8 %y) {
276 ; CHECK-LABEL: @sadd_y_ge_max(
277 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
278 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
279 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
280 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], -1
281 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
282 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
283 ; CHECK-NEXT: ret i8 [[R]]
285 %ao = tail call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %x, i8 %y)
286 %o = extractvalue { i8, i1 } %ao, 1
287 %a = extractvalue { i8, i1 } %ao, 0
288 %c = icmp sge i8 %y, 0
289 %s = select i1 %c, i8 -128, i8 127
290 %r = select i1 %o, i8 %s, i8 %a
297 define i8 @ssub_x_lt_min(i8 %x, i8 %y) {
298 ; CHECK-LABEL: @ssub_x_lt_min(
299 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
300 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
301 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
302 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 0
303 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
304 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
305 ; CHECK-NEXT: ret i8 [[R]]
307 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
308 %o = extractvalue { i8, i1 } %ao, 1
309 %a = extractvalue { i8, i1 } %ao, 0
310 %c = icmp slt i8 %x, 0
311 %s = select i1 %c, i8 127, i8 -128
312 %r = select i1 %o, i8 %s, i8 %a
316 define i8 @ssub_x_lt_max(i8 %x, i8 %y) {
317 ; CHECK-LABEL: @ssub_x_lt_max(
318 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
319 ; CHECK-NEXT: ret i8 [[R]]
321 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
322 %o = extractvalue { i8, i1 } %ao, 1
323 %a = extractvalue { i8, i1 } %ao, 0
324 %c = icmp slt i8 %x, 0
325 %s = select i1 %c, i8 -128, i8 127
326 %r = select i1 %o, i8 %s, i8 %a
330 define i8 @ssub_x_le_min(i8 %x, i8 %y) {
331 ; CHECK-LABEL: @ssub_x_le_min(
332 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
333 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
334 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
335 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1
336 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
337 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
338 ; CHECK-NEXT: ret i8 [[R]]
340 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
341 %o = extractvalue { i8, i1 } %ao, 1
342 %a = extractvalue { i8, i1 } %ao, 0
343 %c = icmp sle i8 %x, 0
344 %s = select i1 %c, i8 127, i8 -128
345 %r = select i1 %o, i8 %s, i8 %a
349 define i8 @ssub_x_le_max(i8 %x, i8 %y) {
350 ; CHECK-LABEL: @ssub_x_le_max(
351 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
352 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
353 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
354 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], 1
355 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
356 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
357 ; CHECK-NEXT: ret i8 [[R]]
359 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
360 %o = extractvalue { i8, i1 } %ao, 1
361 %a = extractvalue { i8, i1 } %ao, 0
362 %c = icmp sle i8 %x, 0
363 %s = select i1 %c, i8 -128, i8 127
364 %r = select i1 %o, i8 %s, i8 %a
368 define i8 @ssub_x_lt2_min(i8 %x, i8 %y) {
369 ; CHECK-LABEL: @ssub_x_lt2_min(
370 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
371 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
372 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
373 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X]], -1
374 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
375 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
376 ; CHECK-NEXT: ret i8 [[R]]
378 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
379 %o = extractvalue { i8, i1 } %ao, 1
380 %a = extractvalue { i8, i1 } %ao, 0
381 %c = icmp slt i8 %x, -1
382 %s = select i1 %c, i8 127, i8 -128
383 %r = select i1 %o, i8 %s, i8 %a
387 define i8 @ssub_x_lt2_max(i8 %x, i8 %y) {
388 ; CHECK-LABEL: @ssub_x_lt2_max(
389 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
390 ; CHECK-NEXT: ret i8 [[R]]
392 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
393 %o = extractvalue { i8, i1 } %ao, 1
394 %a = extractvalue { i8, i1 } %ao, 0
395 %c = icmp slt i8 %x, -1
396 %s = select i1 %c, i8 -128, i8 127
397 %r = select i1 %o, i8 %s, i8 %a
401 define i8 @ssub_x_gt_min(i8 %x, i8 %y) {
402 ; CHECK-LABEL: @ssub_x_gt_min(
403 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
404 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
405 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
406 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0
407 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
408 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
409 ; CHECK-NEXT: ret i8 [[R]]
411 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
412 %o = extractvalue { i8, i1 } %ao, 1
413 %a = extractvalue { i8, i1 } %ao, 0
414 %c = icmp sgt i8 %x, 0
415 %s = select i1 %c, i8 127, i8 -128
416 %r = select i1 %o, i8 %s, i8 %a
420 define i8 @ssub_x_gt_max(i8 %x, i8 %y) {
421 ; CHECK-LABEL: @ssub_x_gt_max(
422 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
423 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
424 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
425 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], 0
426 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
427 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
428 ; CHECK-NEXT: ret i8 [[R]]
430 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
431 %o = extractvalue { i8, i1 } %ao, 1
432 %a = extractvalue { i8, i1 } %ao, 0
433 %c = icmp sgt i8 %x, 0
434 %s = select i1 %c, i8 -128, i8 127
435 %r = select i1 %o, i8 %s, i8 %a
439 define i8 @ssub_x_ge_min(i8 %x, i8 %y) {
440 ; CHECK-LABEL: @ssub_x_ge_min(
441 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
442 ; CHECK-NEXT: ret i8 [[R]]
444 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
445 %o = extractvalue { i8, i1 } %ao, 1
446 %a = extractvalue { i8, i1 } %ao, 0
447 %c = icmp sge i8 %x, 0
448 %s = select i1 %c, i8 127, i8 -128
449 %r = select i1 %o, i8 %s, i8 %a
453 define i8 @ssub_x_ge_max(i8 %x, i8 %y) {
454 ; CHECK-LABEL: @ssub_x_ge_max(
455 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
456 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
457 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
458 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -1
459 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
460 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
461 ; CHECK-NEXT: ret i8 [[R]]
463 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
464 %o = extractvalue { i8, i1 } %ao, 1
465 %a = extractvalue { i8, i1 } %ao, 0
466 %c = icmp sge i8 %x, 0
467 %s = select i1 %c, i8 -128, i8 127
468 %r = select i1 %o, i8 %s, i8 %a
472 define i8 @ssub_x_gt2_min(i8 %x, i8 %y) {
473 ; CHECK-LABEL: @ssub_x_gt2_min(
474 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
475 ; CHECK-NEXT: ret i8 [[R]]
477 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
478 %o = extractvalue { i8, i1 } %ao, 1
479 %a = extractvalue { i8, i1 } %ao, 0
480 %c = icmp sgt i8 %x, -2
481 %s = select i1 %c, i8 127, i8 -128
482 %r = select i1 %o, i8 %s, i8 %a
486 define i8 @ssub_x_gt2_max(i8 %x, i8 %y) {
487 ; CHECK-LABEL: @ssub_x_gt2_max(
488 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
489 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
490 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
491 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X]], -2
492 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
493 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
494 ; CHECK-NEXT: ret i8 [[R]]
496 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
497 %o = extractvalue { i8, i1 } %ao, 1
498 %a = extractvalue { i8, i1 } %ao, 0
499 %c = icmp sgt i8 %x, -2
500 %s = select i1 %c, i8 -128, i8 127
501 %r = select i1 %o, i8 %s, i8 %a
506 define i8 @ssub_y_lt_min(i8 %x, i8 %y) {
507 ; CHECK-LABEL: @ssub_y_lt_min(
508 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
509 ; CHECK-NEXT: ret i8 [[R]]
511 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
512 %o = extractvalue { i8, i1 } %ao, 1
513 %a = extractvalue { i8, i1 } %ao, 0
514 %c = icmp slt i8 %y, 0
515 %s = select i1 %c, i8 127, i8 -128
516 %r = select i1 %o, i8 %s, i8 %a
520 define i8 @ssub_y_lt_max(i8 %x, i8 %y) {
521 ; CHECK-LABEL: @ssub_y_lt_max(
522 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
523 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
524 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
525 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 0
526 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
527 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
528 ; CHECK-NEXT: ret i8 [[R]]
530 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
531 %o = extractvalue { i8, i1 } %ao, 1
532 %a = extractvalue { i8, i1 } %ao, 0
533 %c = icmp slt i8 %y, 0
534 %s = select i1 %c, i8 -128, i8 127
535 %r = select i1 %o, i8 %s, i8 %a
539 define i8 @ssub_y_le_min(i8 %x, i8 %y) {
540 ; CHECK-LABEL: @ssub_y_le_min(
541 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
542 ; CHECK-NEXT: ret i8 [[R]]
544 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
545 %o = extractvalue { i8, i1 } %ao, 1
546 %a = extractvalue { i8, i1 } %ao, 0
547 %c = icmp sle i8 %y, 0
548 %s = select i1 %c, i8 127, i8 -128
549 %r = select i1 %o, i8 %s, i8 %a
553 define i8 @ssub_y_le_max(i8 %x, i8 %y) {
554 ; CHECK-LABEL: @ssub_y_le_max(
555 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
556 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
557 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
558 ; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[Y]], 1
559 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 -128, i8 127
560 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
561 ; CHECK-NEXT: ret i8 [[R]]
563 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
564 %o = extractvalue { i8, i1 } %ao, 1
565 %a = extractvalue { i8, i1 } %ao, 0
566 %c = icmp sle i8 %y, 0
567 %s = select i1 %c, i8 -128, i8 127
568 %r = select i1 %o, i8 %s, i8 %a
572 define i8 @ssub_y_gt_min(i8 %x, i8 %y) {
573 ; CHECK-LABEL: @ssub_y_gt_min(
574 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
575 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
576 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
577 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], 0
578 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
579 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
580 ; CHECK-NEXT: ret i8 [[R]]
582 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
583 %o = extractvalue { i8, i1 } %ao, 1
584 %a = extractvalue { i8, i1 } %ao, 0
585 %c = icmp sgt i8 %y, 0
586 %s = select i1 %c, i8 127, i8 -128
587 %r = select i1 %o, i8 %s, i8 %a
591 define i8 @ssub_y_gt_max(i8 %x, i8 %y) {
592 ; CHECK-LABEL: @ssub_y_gt_max(
593 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
594 ; CHECK-NEXT: ret i8 [[R]]
596 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
597 %o = extractvalue { i8, i1 } %ao, 1
598 %a = extractvalue { i8, i1 } %ao, 0
599 %c = icmp sgt i8 %y, 0
600 %s = select i1 %c, i8 -128, i8 127
601 %r = select i1 %o, i8 %s, i8 %a
605 define i8 @ssub_y_ge_min(i8 %x, i8 %y) {
606 ; CHECK-LABEL: @ssub_y_ge_min(
607 ; CHECK-NEXT: [[AO:%.*]] = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
608 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i8, i1 } [[AO]], 1
609 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i8, i1 } [[AO]], 0
610 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[Y]], -1
611 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 127, i8 -128
612 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i8 [[S]], i8 [[A]]
613 ; CHECK-NEXT: ret i8 [[R]]
615 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
616 %o = extractvalue { i8, i1 } %ao, 1
617 %a = extractvalue { i8, i1 } %ao, 0
618 %c = icmp sge i8 %y, 0
619 %s = select i1 %c, i8 127, i8 -128
620 %r = select i1 %o, i8 %s, i8 %a
624 define i8 @ssub_y_ge_max(i8 %x, i8 %y) {
625 ; CHECK-LABEL: @ssub_y_ge_max(
626 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
627 ; CHECK-NEXT: ret i8 [[R]]
629 %ao = tail call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %x, i8 %y)
630 %o = extractvalue { i8, i1 } %ao, 1
631 %a = extractvalue { i8, i1 } %ao, 0
632 %c = icmp sge i8 %y, 0
633 %s = select i1 %c, i8 -128, i8 127
634 %r = select i1 %o, i8 %s, i8 %a
639 define i32 @sadd_i32(i32 %x, i32 %y) {
640 ; CHECK-LABEL: @sadd_i32(
641 ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
642 ; CHECK-NEXT: ret i32 [[R]]
644 %ao = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
645 %o = extractvalue { i32, i1 } %ao, 1
646 %a = extractvalue { i32, i1 } %ao, 0
647 %c = icmp slt i32 %x, 0
648 %s = select i1 %c, i32 -2147483648, i32 2147483647
649 %r = select i1 %o, i32 %s, i32 %a
653 define i32 @ssub_i32(i32 %x, i32 %y) {
654 ; CHECK-LABEL: @ssub_i32(
655 ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
656 ; CHECK-NEXT: ret i32 [[R]]
658 %ao = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
659 %o = extractvalue { i32, i1 } %ao, 1
660 %a = extractvalue { i32, i1 } %ao, 0
661 %c = icmp slt i32 %x, 0
662 %s = select i1 %c, i32 -2147483648, i32 2147483647
663 %r = select i1 %o, i32 %s, i32 %a
667 define i32 @sadd_bounds(i32 %x, i32 %y) {
668 ; CHECK-LABEL: @sadd_bounds(
669 ; CHECK-NEXT: [[AO:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
670 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i32, i1 } [[AO]], 1
671 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i32, i1 } [[AO]], 0
672 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X]], 0
673 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 -128, i32 127
674 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i32 [[S]], i32 [[A]]
675 ; CHECK-NEXT: ret i32 [[R]]
677 %ao = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
678 %o = extractvalue { i32, i1 } %ao, 1
679 %a = extractvalue { i32, i1 } %ao, 0
680 %c = icmp slt i32 %x, 0
681 %s = select i1 %c, i32 -128, i32 127
682 %r = select i1 %o, i32 %s, i32 %a
686 define i32 @ssub_bounds(i32 %x, i32 %y) {
687 ; CHECK-LABEL: @ssub_bounds(
688 ; CHECK-NEXT: [[AO:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
689 ; CHECK-NEXT: [[O:%.*]] = extractvalue { i32, i1 } [[AO]], 1
690 ; CHECK-NEXT: [[A:%.*]] = extractvalue { i32, i1 } [[AO]], 0
691 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X]], 0
692 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 -128, i32 127
693 ; CHECK-NEXT: [[R:%.*]] = select i1 [[O]], i32 [[S]], i32 [[A]]
694 ; CHECK-NEXT: ret i32 [[R]]
696 %ao = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
697 %o = extractvalue { i32, i1 } %ao, 1
698 %a = extractvalue { i32, i1 } %ao, 0
699 %c = icmp slt i32 %x, 0
700 %s = select i1 %c, i32 -128, i32 127
701 %r = select i1 %o, i32 %s, i32 %a
705 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %0, i32 %1)
706 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32 %0, i32 %1)
707 declare { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %0, i8 %1)
708 declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %0, i8 %1)
709 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %0, i32 %1)
710 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %0, i32 %1)