xref: /llvm-project/llvm/test/Transforms/InstCombine/overflow_to_sat.ll (revision acdc419c897f8a9414c7a00c8908ac32312afee2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4define 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]]
8;
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
14}
15
16define 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]]
20;
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
26}
27
28
29define 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]]
38;
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
46}
47
48define 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]]
52;
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
60}
61
62define 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]]
71;
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
79}
80
81define 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]]
85;
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
93}
94
95define 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]]
99;
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
107}
108
109define 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]]
118;
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
126}
127
128define 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]]
132;
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
140}
141
142define 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]]
151;
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
159}
160
161
162define 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]]
171;
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
179}
180
181define 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]]
185;
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
193}
194
195define 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]]
204;
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
212}
213
214define 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]]
218;
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
226}
227
228define 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]]
232;
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
240}
241
242define 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]]
251;
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
259}
260
261define 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]]
265;
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
273}
274
275define 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]]
284;
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
292}
293
294
295
296
297define 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]]
306;
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
314}
315
316define 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]]
320;
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
328}
329
330define 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]]
339;
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
347}
348
349define 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]]
358;
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
366}
367
368define 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]]
377;
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
385}
386
387define 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]]
391;
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
399}
400
401define 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]]
410;
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
418}
419
420define 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]]
429;
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
437}
438
439define 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]]
443;
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
451}
452
453define 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]]
462;
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
470}
471
472define 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]]
476;
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
484}
485
486define 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]]
495;
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
503}
504
505
506define 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]]
510;
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
518}
519
520define 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]]
529;
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
537}
538
539define 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]]
543;
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
551}
552
553define 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]]
562;
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
570}
571
572define 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]]
581;
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
589}
590
591define 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]]
595;
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
603}
604
605define 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]]
614;
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
622}
623
624define 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]]
628;
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
636}
637
638
639define 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]]
643;
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
651}
652
653define 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]]
657;
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
665}
666
667define 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]]
676;
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
684}
685
686define 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]]
695;
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
703}
704
705declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %0, i32 %1)
706declare { i32, i1 } @llvm.usub.with.overflow.i32(i32 %0, i32 %1)
707declare { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %0, i8 %1)
708declare { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %0, i8 %1)
709declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %0, i32 %1)
710declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %0, i32 %1)
711