[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / overflow_to_sat.ll
blobaf56f5703af572217d475bf70c95ec0a9c3fde63
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) {
5 ; CHECK-LABEL: @uadd(
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
13   ret i32 %s
16 define i32 @usub(i32 %x, i32 %y) {
17 ; CHECK-LABEL: @usub(
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
25   ret i32 %s
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
45   ret i8 %r
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
59   ret i8 %r
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
78   ret i8 %r
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
92   ret i8 %r
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
106   ret i8 %r
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
125   ret i8 %r
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
139   ret i8 %r
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
158   ret i8 %r
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
178   ret i8 %r
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
192   ret i8 %r
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
211   ret i8 %r
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
225   ret i8 %r
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
239   ret i8 %r
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
258   ret i8 %r
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
272   ret i8 %r
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
291   ret i8 %r
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
313   ret i8 %r
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
327   ret i8 %r
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
346   ret i8 %r
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
365   ret i8 %r
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
384   ret i8 %r
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
398   ret i8 %r
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
417   ret i8 %r
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
436   ret i8 %r
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
450   ret i8 %r
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
469   ret i8 %r
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
483   ret i8 %r
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
502   ret i8 %r
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
517   ret i8 %r
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
536   ret i8 %r
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
550   ret i8 %r
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
569   ret i8 %r
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
588   ret i8 %r
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
602   ret i8 %r
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
621   ret i8 %r
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
635   ret i8 %r
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
650   ret i32 %r
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
664   ret i32 %r
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
683   ret i32 %r
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
702   ret i32 %r
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)