Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / saturating-add-sub.ll
blob6fb12612f2f721fba7e32b0b8d03c3d02bada1d9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; TODO: the instructions having poison operands should be folded to poison
6 declare i3 @llvm.uadd.sat.i3(i3, i3)
7 declare i8 @llvm.uadd.sat.i8(i8, i8)
8 declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
9 declare <2 x i9> @llvm.uadd.sat.v2i9(<2 x i9>, <2 x i9>)
11 declare i8 @llvm.sadd.sat.i8(i8, i8)
12 declare <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8>, <2 x i8>)
14 declare i8 @llvm.usub.sat.i8(i8, i8)
15 declare i8 @llvm.ssub.sat.i8(i8, i8)
16 declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
17 declare <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8>, <2 x i8>)
19 define i8 @uadd_scalar_0(i8 %a) {
20 ; CHECK-LABEL: @uadd_scalar_0(
21 ; CHECK-NEXT:    ret i8 [[A:%.*]]
23   %x1 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 0)
24   ret i8 %x1
27 define <2 x i8> @uadd_vector_0(<2 x i8> %a) {
28 ; CHECK-LABEL: @uadd_vector_0(
29 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
31   %x1v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> zeroinitializer)
32   ret <2 x i8> %x1v
35 define i3 @uadd_scalar_0_commute(i3 %a) {
36 ; CHECK-LABEL: @uadd_scalar_0_commute(
37 ; CHECK-NEXT:    ret i3 [[A:%.*]]
39   %x2 = call i3 @llvm.uadd.sat.i3(i3 0, i3 %a)
40   ret i3 %x2
43 define <2 x i8> @uadd_vector_0_commute(<2 x i8> %a) {
44 ; CHECK-LABEL: @uadd_vector_0_commute(
45 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
47   %x2v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 0, i8 undef>, <2 x i8> %a)
48   ret <2 x i8> %x2v
51 define i8 @uadd_scalar_maxval(i8 %a) {
52 ; CHECK-LABEL: @uadd_scalar_maxval(
53 ; CHECK-NEXT:    ret i8 -1
55   %x3 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 255)
56   ret i8 %x3
59 define <2 x i9> @uadd_vector_maxval(<2 x i9> %a) {
60 ; CHECK-LABEL: @uadd_vector_maxval(
61 ; CHECK-NEXT:    ret <2 x i9> <i9 -1, i9 -1>
63   %x3v = call <2 x i9> @llvm.uadd.sat.v2i9(<2 x i9> %a, <2 x i9> <i9 511, i9 511>)
64   ret <2 x i9> %x3v
67 define i3 @uadd_scalar_maxval_commute(i3 %a) {
68 ; CHECK-LABEL: @uadd_scalar_maxval_commute(
69 ; CHECK-NEXT:    ret i3 -1
71   %x4 = call i3 @llvm.uadd.sat.i3(i3 7, i3 %a)
72   ret i3 %x4
75 define <2 x i8> @uadd_vector_maxval_commute(<2 x i8> %a) {
76 ; CHECK-LABEL: @uadd_vector_maxval_commute(
77 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
79   %x4v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 255, i8 255>, <2 x i8> %a)
80   ret <2 x i8> %x4v
83 define i8 @uadd_scalar_undef(i8 %a) {
84 ; CHECK-LABEL: @uadd_scalar_undef(
85 ; CHECK-NEXT:    ret i8 -1
87   %x5 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 undef)
88   ret i8 %x5
91 define i8 @uadd_scalar_poison(i8 %a) {
92 ; CHECK-LABEL: @uadd_scalar_poison(
93 ; CHECK-NEXT:    ret i8 -1
95   %x5 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 poison)
96   ret i8 %x5
99 define <2 x i8> @uadd_vector_undef(<2 x i8> %a) {
100 ; CHECK-LABEL: @uadd_vector_undef(
101 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
103   %x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 undef, i8 undef>)
104   ret <2 x i8> %x5v
107 define <2 x i8> @uadd_vector_poison(<2 x i8> %a) {
108 ; CHECK-LABEL: @uadd_vector_poison(
109 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
111   %x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
112   ret <2 x i8> %x5v
115 define i8 @uadd_scalar_undef_commute(i8 %a) {
116 ; CHECK-LABEL: @uadd_scalar_undef_commute(
117 ; CHECK-NEXT:    ret i8 -1
119   %x6 = call i8 @llvm.uadd.sat.i8(i8 undef, i8 %a)
120   ret i8 %x6
123 define i8 @uadd_scalar_poison_commute(i8 %a) {
124 ; CHECK-LABEL: @uadd_scalar_poison_commute(
125 ; CHECK-NEXT:    ret i8 -1
127   %x6 = call i8 @llvm.uadd.sat.i8(i8 poison, i8 %a)
128   ret i8 %x6
131 define <2 x i8> @uadd_vector_undef_commute(<2 x i8> %a) {
132 ; CHECK-LABEL: @uadd_vector_undef_commute(
133 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
135   %x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> undef, <2 x i8> %a)
136   ret <2 x i8> %x5v
139 define <2 x i8> @uadd_vector_poison_commute(<2 x i8> %a) {
140 ; CHECK-LABEL: @uadd_vector_poison_commute(
141 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
143   %x5v = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
144   ret <2 x i8> %x5v
147 define i8 @sadd_scalar_0(i8 %a) {
148 ; CHECK-LABEL: @sadd_scalar_0(
149 ; CHECK-NEXT:    ret i8 [[A:%.*]]
151   %y1 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 0)
152   ret i8 %y1
155 define <2 x i8> @sadd_vector_0(<2 x i8> %a) {
156 ; CHECK-LABEL: @sadd_vector_0(
157 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
159   %y1v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 undef, i8 0>)
160   ret <2 x i8> %y1v
163 define i8 @sadd_scalar_0_commute(i8 %a) {
164 ; CHECK-LABEL: @sadd_scalar_0_commute(
165 ; CHECK-NEXT:    ret i8 [[A:%.*]]
167   %y2 = call i8 @llvm.sadd.sat.i8(i8 0, i8 %a)
168   ret i8 %y2
171 define <2 x i8> @sadd_vector_0_commute(<2 x i8> %a) {
172 ; CHECK-LABEL: @sadd_vector_0_commute(
173 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
175   %y2v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> zeroinitializer, <2 x i8> %a)
176   ret <2 x i8> %y2v
179 define i8 @sadd_scalar_maxval(i8 %a) {
180 ; CHECK-LABEL: @sadd_scalar_maxval(
181 ; CHECK-NEXT:    [[Y3:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 127)
182 ; CHECK-NEXT:    ret i8 [[Y3]]
184   %y3 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 127)
185   ret i8 %y3
188 define <2 x i8> @sadd_vector_maxval(<2 x i8> %a) {
189 ; CHECK-LABEL: @sadd_vector_maxval(
190 ; CHECK-NEXT:    [[Y3V:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 127, i8 127>)
191 ; CHECK-NEXT:    ret <2 x i8> [[Y3V]]
193   %y3v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 127, i8 127>)
194   ret <2 x i8> %y3v
197 define i8 @sadd_scalar_maxval_commute(i8 %a) {
198 ; CHECK-LABEL: @sadd_scalar_maxval_commute(
199 ; CHECK-NEXT:    [[Y4:%.*]] = call i8 @llvm.sadd.sat.i8(i8 127, i8 [[A:%.*]])
200 ; CHECK-NEXT:    ret i8 [[Y4]]
202   %y4 = call i8 @llvm.sadd.sat.i8(i8 127, i8 %a)
203   ret i8 %y4
206 define <2 x i8> @sadd_vector_maxval_commute(<2 x i8> %a) {
207 ; CHECK-LABEL: @sadd_vector_maxval_commute(
208 ; CHECK-NEXT:    [[Y4V:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 127>, <2 x i8> [[A:%.*]])
209 ; CHECK-NEXT:    ret <2 x i8> [[Y4V]]
211   %y4v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 127>, <2 x i8> %a)
212   ret <2 x i8> %y4v
215 define i8 @sadd_scalar_undef(i8 %a) {
216 ; CHECK-LABEL: @sadd_scalar_undef(
217 ; CHECK-NEXT:    ret i8 -1
219   %y5 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 undef)
220   ret i8 %y5
223 define i8 @sadd_scalar_poison(i8 %a) {
224 ; CHECK-LABEL: @sadd_scalar_poison(
225 ; CHECK-NEXT:    ret i8 -1
227   %y5 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 poison)
228   ret i8 %y5
231 define <2 x i8> @sadd_vector_undef(<2 x i8> %a) {
232 ; CHECK-LABEL: @sadd_vector_undef(
233 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
235   %y5v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> undef)
236   ret <2 x i8> %y5v
239 define <2 x i8> @sadd_vector_poison(<2 x i8> %a) {
240 ; CHECK-LABEL: @sadd_vector_poison(
241 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
243   %y5v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
244   ret <2 x i8> %y5v
247 define i8 @sadd_scalar_undef_commute(i8 %a) {
248 ; CHECK-LABEL: @sadd_scalar_undef_commute(
249 ; CHECK-NEXT:    ret i8 -1
251   %y6 = call i8 @llvm.sadd.sat.i8(i8 undef, i8 %a)
252   ret i8 %y6
255 define i8 @sadd_scalar_poison_commute(i8 %a) {
256 ; CHECK-LABEL: @sadd_scalar_poison_commute(
257 ; CHECK-NEXT:    ret i8 -1
259   %y6 = call i8 @llvm.sadd.sat.i8(i8 poison, i8 %a)
260   ret i8 %y6
263 define <2 x i8> @sadd_vector_undef_commute(<2 x i8> %a) {
264 ; CHECK-LABEL: @sadd_vector_undef_commute(
265 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
267   %y6v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> %a)
268   ret <2 x i8> %y6v
271 define <2 x i8> @sadd_vector_poison_commute(<2 x i8> %a) {
272 ; CHECK-LABEL: @sadd_vector_poison_commute(
273 ; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
275   %y6v = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> %a)
276   ret <2 x i8> %y6v
279 define i8 @usub_scalar_0(i8 %a) {
280 ; CHECK-LABEL: @usub_scalar_0(
281 ; CHECK-NEXT:    ret i8 [[A:%.*]]
283   %x1 = call i8 @llvm.usub.sat.i8(i8 %a, i8 0)
284   ret i8 %x1
287 define <2 x i8> @usub_vector_0(<2 x i8> %a) {
288 ; CHECK-LABEL: @usub_vector_0(
289 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
291   %x1v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 0, i8 0>)
292   ret <2 x i8> %x1v
295 define i8 @usub_scalar_0_commute(i8 %a) {
296 ; CHECK-LABEL: @usub_scalar_0_commute(
297 ; CHECK-NEXT:    ret i8 0
299   %x2 = call i8 @llvm.usub.sat.i8(i8 0, i8 %a)
300   ret i8 %x2
303 define <2 x i8> @usub_vector_0_commute(<2 x i8> %a) {
304 ; CHECK-LABEL: @usub_vector_0_commute(
305 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
307   %x2v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 0, i8 0>, <2 x i8> %a)
308   ret <2 x i8> %x2v
311 define i8 @usub_scalar_maxval(i8 %a) {
312 ; CHECK-LABEL: @usub_scalar_maxval(
313 ; CHECK-NEXT:    ret i8 0
315   %x3 = call i8 @llvm.usub.sat.i8(i8 %a, i8 255)
316   ret i8 %x3
319 define <2 x i8> @usub_vector_maxval(<2 x i8> %a) {
320 ; CHECK-LABEL: @usub_vector_maxval(
321 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
323   %x3v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 255, i8 255>)
324   ret <2 x i8> %x3v
327 define i8 @usub_scalar_undef(i8 %a) {
328 ; CHECK-LABEL: @usub_scalar_undef(
329 ; CHECK-NEXT:    ret i8 0
331   %x4 = call i8 @llvm.usub.sat.i8(i8 %a, i8 undef)
332   ret i8 %x4
335 define i8 @usub_scalar_poison(i8 %a) {
336 ; CHECK-LABEL: @usub_scalar_poison(
337 ; CHECK-NEXT:    ret i8 0
339   %x4 = call i8 @llvm.usub.sat.i8(i8 %a, i8 poison)
340   ret i8 %x4
343 define <2 x i8> @usub_vector_undef(<2 x i8> %a) {
344 ; CHECK-LABEL: @usub_vector_undef(
345 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
347   %x4v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 undef, i8 undef>)
348   ret <2 x i8> %x4v
351 define <2 x i8> @usub_vector_poison(<2 x i8> %a) {
352 ; CHECK-LABEL: @usub_vector_poison(
353 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
355   %x4v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 poison, i8 poison>)
356   ret <2 x i8> %x4v
359 define i8 @usub_scalar_undef_commute(i8 %a) {
360 ; CHECK-LABEL: @usub_scalar_undef_commute(
361 ; CHECK-NEXT:    ret i8 0
363   %x5 = call i8 @llvm.usub.sat.i8(i8 undef, i8 %a)
364   ret i8 %x5
367 define i8 @usub_scalar_poison_commute(i8 %a) {
368 ; CHECK-LABEL: @usub_scalar_poison_commute(
369 ; CHECK-NEXT:    ret i8 0
371   %x5 = call i8 @llvm.usub.sat.i8(i8 poison, i8 %a)
372   ret i8 %x5
375 define <2 x i8> @usub_vector_undef_commute(<2 x i8> %a) {
376 ; CHECK-LABEL: @usub_vector_undef_commute(
377 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
379   %x5v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 undef, i8 undef>, <2 x i8> %a)
380   ret <2 x i8> %x5v
383 define <2 x i8> @usub_vector_poison_commute(<2 x i8> %a) {
384 ; CHECK-LABEL: @usub_vector_poison_commute(
385 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
387   %x5v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
388   ret <2 x i8> %x5v
391 define i8 @usub_scalar_same(i8 %a) {
392 ; CHECK-LABEL: @usub_scalar_same(
393 ; CHECK-NEXT:    ret i8 0
395   %x6 = call i8 @llvm.usub.sat.i8(i8 %a, i8 %a)
396   ret i8 %x6
399 define <2 x i8> @usub_vector_same(<2 x i8> %a) {
400 ; CHECK-LABEL: @usub_vector_same(
401 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
403   %x6v = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> %a)
404   ret <2 x i8> %x6v
407 define i8 @ssub_scalar_0(i8 %a) {
408 ; CHECK-LABEL: @ssub_scalar_0(
409 ; CHECK-NEXT:    ret i8 [[A:%.*]]
411   %y1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 0)
412   ret i8 %y1
415 define <2 x i8> @ssub_vector_0(<2 x i8> %a) {
416 ; CHECK-LABEL: @ssub_vector_0(
417 ; CHECK-NEXT:    ret <2 x i8> [[A:%.*]]
419   %y1v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 0, i8 0>)
420   ret <2 x i8> %y1v
423 define i8 @ssub_scalar_0_commute(i8 %a) {
424 ; CHECK-LABEL: @ssub_scalar_0_commute(
425 ; CHECK-NEXT:    [[Y2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 0, i8 [[A:%.*]])
426 ; CHECK-NEXT:    ret i8 [[Y2]]
428   %y2 = call i8 @llvm.ssub.sat.i8(i8 0, i8 %a)
429   ret i8 %y2
432 define <2 x i8> @ssub_vector_0_commute(<2 x i8> %a) {
433 ; CHECK-LABEL: @ssub_vector_0_commute(
434 ; CHECK-NEXT:    [[Y2V:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> zeroinitializer, <2 x i8> [[A:%.*]])
435 ; CHECK-NEXT:    ret <2 x i8> [[Y2V]]
437   %y2v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 0, i8 0>, <2 x i8> %a)
438   ret <2 x i8> %y2v
441 define i8 @ssub_scalar_maxval(i8 %a) {
442 ; CHECK-LABEL: @ssub_scalar_maxval(
443 ; CHECK-NEXT:    [[Y3:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 127)
444 ; CHECK-NEXT:    ret i8 [[Y3]]
446   %y3 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 127)
447   ret i8 %y3
450 define <2 x i8> @ssub_vector_maxval(<2 x i8> %a) {
451 ; CHECK-LABEL: @ssub_vector_maxval(
452 ; CHECK-NEXT:    [[Y3V:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 127, i8 127>)
453 ; CHECK-NEXT:    ret <2 x i8> [[Y3V]]
455   %y3v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 127, i8 127>)
456   ret <2 x i8> %y3v
459 define i8 @ssub_scalar_undef(i8 %a) {
460 ; CHECK-LABEL: @ssub_scalar_undef(
461 ; CHECK-NEXT:    ret i8 0
463   %y4 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 undef)
464   ret i8 %y4
467 define i8 @ssub_scalar_poison(i8 %a) {
468 ; CHECK-LABEL: @ssub_scalar_poison(
469 ; CHECK-NEXT:    ret i8 0
471   %y4 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 poison)
472   ret i8 %y4
475 define <2 x i8> @ssub_vector_undef(<2 x i8> %a) {
476 ; CHECK-LABEL: @ssub_vector_undef(
477 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
479   %y4v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> undef)
480   ret <2 x i8> %y4v
483 define <2 x i8> @ssub_vector_poison(<2 x i8> %a) {
484 ; CHECK-LABEL: @ssub_vector_poison(
485 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
487   %y4v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> poison)
488   ret <2 x i8> %y4v
491 define i8 @ssub_scalar_undef_commute(i8 %a) {
492 ; CHECK-LABEL: @ssub_scalar_undef_commute(
493 ; CHECK-NEXT:    ret i8 0
495   %y5 = call i8 @llvm.ssub.sat.i8(i8 undef, i8 %a)
496   ret i8 %y5
499 define i8 @ssub_scalar_poison_commute(i8 %a) {
500 ; CHECK-LABEL: @ssub_scalar_poison_commute(
501 ; CHECK-NEXT:    ret i8 0
503   %y5 = call i8 @llvm.ssub.sat.i8(i8 poison, i8 %a)
504   ret i8 %y5
507 define <2 x i8> @ssub_vector_undef_commute(<2 x i8> %a) {
508 ; CHECK-LABEL: @ssub_vector_undef_commute(
509 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
511   %y5v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 undef>, <2 x i8> %a)
512   ret <2 x i8> %y5v
515 define <2 x i8> @ssub_vector_poison_commute(<2 x i8> %a) {
516 ; CHECK-LABEL: @ssub_vector_poison_commute(
517 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
519   %y5v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 poison>, <2 x i8> %a)
520   ret <2 x i8> %y5v
523 define i8 @ssub_scalar_same(i8 %a) {
524 ; CHECK-LABEL: @ssub_scalar_same(
525 ; CHECK-NEXT:    ret i8 0
527   %y6 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 %a)
528   ret i8 %y6
531 define <2 x i8> @ssub_vector_same(<2 x i8> %a) {
532 ; CHECK-LABEL: @ssub_vector_same(
533 ; CHECK-NEXT:    ret <2 x i8> zeroinitializer
535   %y6v = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> %a)
536   ret <2 x i8> %y6v
539 define i1 @uadd_icmp_op0_known(i8 %a) {
540 ; CHECK-LABEL: @uadd_icmp_op0_known(
541 ; CHECK-NEXT:    ret i1 true
543   %b = call i8 @llvm.uadd.sat.i8(i8 10, i8 %a)
544   %c = icmp uge i8 %b, 10
545   ret i1 %c
548 define i1 @uadd_icmp_op0_unknown(i8 %a) {
549 ; CHECK-LABEL: @uadd_icmp_op0_unknown(
550 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.uadd.sat.i8(i8 10, i8 [[A:%.*]])
551 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[B]], 10
552 ; CHECK-NEXT:    ret i1 [[C]]
554   %b = call i8 @llvm.uadd.sat.i8(i8 10, i8 %a)
555   %c = icmp ugt i8 %b, 10
556   ret i1 %c
559 define i1 @uadd_icmp_op1_known(i8 %a) {
560 ; CHECK-LABEL: @uadd_icmp_op1_known(
561 ; CHECK-NEXT:    ret i1 true
563   %b = call i8 @llvm.uadd.sat.i8(i8 %a, i8 10)
564   %c = icmp uge i8 %b, 10
565   ret i1 %c
568 define i1 @uadd_icmp_op1_unknown(i8 %a) {
569 ; CHECK-LABEL: @uadd_icmp_op1_unknown(
570 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 10)
571 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[B]], 10
572 ; CHECK-NEXT:    ret i1 [[C]]
574   %b = call i8 @llvm.uadd.sat.i8(i8 %a, i8 10)
575   %c = icmp ugt i8 %b, 10
576   ret i1 %c
579 define i1 @sadd_icmp_op0_pos_known(i8 %a) {
580 ; CHECK-LABEL: @sadd_icmp_op0_pos_known(
581 ; CHECK-NEXT:    ret i1 true
583   %b = call i8 @llvm.sadd.sat.i8(i8 10, i8 %a)
584   %c = icmp sge i8 %b, -118
585   ret i1 %c
588 define i1 @sadd_icmp_op0_pos_unknown(i8 %a) {
589 ; CHECK-LABEL: @sadd_icmp_op0_pos_unknown(
590 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.sadd.sat.i8(i8 10, i8 [[A:%.*]])
591 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[B]], -118
592 ; CHECK-NEXT:    ret i1 [[C]]
594   %b = call i8 @llvm.sadd.sat.i8(i8 10, i8 %a)
595   %c = icmp sgt i8 %b, -118
596   ret i1 %c
599 define i1 @sadd_icmp_op0_neg_known(i8 %a) {
600 ; CHECK-LABEL: @sadd_icmp_op0_neg_known(
601 ; CHECK-NEXT:    ret i1 true
603   %b = call i8 @llvm.sadd.sat.i8(i8 -10, i8 %a)
604   %c = icmp sle i8 %b, 117
605   ret i1 %c
608 define i1 @sadd_icmp_op0_neg_unknown(i8 %a) {
609 ; CHECK-LABEL: @sadd_icmp_op0_neg_unknown(
610 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.sadd.sat.i8(i8 -10, i8 [[A:%.*]])
611 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[B]], 117
612 ; CHECK-NEXT:    ret i1 [[C]]
614   %b = call i8 @llvm.sadd.sat.i8(i8 -10, i8 %a)
615   %c = icmp slt i8 %b, 117
616   ret i1 %c
619 define i1 @sadd_icmp_op1_pos_known(i8 %a) {
620 ; CHECK-LABEL: @sadd_icmp_op1_pos_known(
621 ; CHECK-NEXT:    ret i1 true
623   %b = call i8 @llvm.sadd.sat.i8(i8 %a, i8 10)
624   %c = icmp sge i8 %b, -118
625   ret i1 %c
628 define i1 @sadd_icmp_op1_pos_unknown(i8 %a) {
629 ; CHECK-LABEL: @sadd_icmp_op1_pos_unknown(
630 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 10)
631 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[B]], -118
632 ; CHECK-NEXT:    ret i1 [[C]]
634   %b = call i8 @llvm.sadd.sat.i8(i8 %a, i8 10)
635   %c = icmp sgt i8 %b, -118
636   ret i1 %c
639 define i1 @sadd_icmp_op1_neg_known(i8 %a) {
640 ; CHECK-LABEL: @sadd_icmp_op1_neg_known(
641 ; CHECK-NEXT:    ret i1 true
643   %b = call i8 @llvm.sadd.sat.i8(i8 %a, i8 -10)
644   %c = icmp sle i8 %b, 117
645   ret i1 %c
648 define i1 @sadd_icmp_op1_neg_unknown(i8 %a) {
649 ; CHECK-LABEL: @sadd_icmp_op1_neg_unknown(
650 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
651 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[B]], 117
652 ; CHECK-NEXT:    ret i1 [[C]]
654   %b = call i8 @llvm.sadd.sat.i8(i8 %a, i8 -10)
655   %c = icmp slt i8 %b, 117
656   ret i1 %c
659 define i1 @usub_icmp_op0_known(i8 %a) {
660 ; CHECK-LABEL: @usub_icmp_op0_known(
661 ; CHECK-NEXT:    ret i1 true
663   %b = call i8 @llvm.usub.sat.i8(i8 10, i8 %a)
664   %c = icmp ule i8 %b, 10
665   ret i1 %c
668 define i1 @usub_icmp_op0_unknown(i8 %a) {
669 ; CHECK-LABEL: @usub_icmp_op0_unknown(
670 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.usub.sat.i8(i8 10, i8 [[A:%.*]])
671 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[B]], 10
672 ; CHECK-NEXT:    ret i1 [[C]]
674   %b = call i8 @llvm.usub.sat.i8(i8 10, i8 %a)
675   %c = icmp ult i8 %b, 10
676   ret i1 %c
679 define i1 @usub_icmp_op1_known(i8 %a) {
680 ; CHECK-LABEL: @usub_icmp_op1_known(
681 ; CHECK-NEXT:    ret i1 true
683   %b = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
684   %c = icmp ule i8 %b, 245
685   ret i1 %c
688 define i1 @usub_icmp_op1_unknown(i8 %a) {
689 ; CHECK-LABEL: @usub_icmp_op1_unknown(
690 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
691 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[B]], -11
692 ; CHECK-NEXT:    ret i1 [[C]]
694   %b = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
695   %c = icmp ult i8 %b, 245
696   ret i1 %c
699 define i1 @ssub_icmp_op0_pos_known(i8 %a) {
700 ; CHECK-LABEL: @ssub_icmp_op0_pos_known(
701 ; CHECK-NEXT:    ret i1 true
703   %b = call i8 @llvm.ssub.sat.i8(i8 10, i8 %a)
704   %c = icmp sge i8 %b, -117
705   ret i1 %c
708 define i1 @ssub_icmp_op0_pos_unknown(i8 %a) {
709 ; CHECK-LABEL: @ssub_icmp_op0_pos_unknown(
710 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.ssub.sat.i8(i8 10, i8 [[A:%.*]])
711 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[B]], -117
712 ; CHECK-NEXT:    ret i1 [[C]]
714   %b = call i8 @llvm.ssub.sat.i8(i8 10, i8 %a)
715   %c = icmp sgt i8 %b, -117
716   ret i1 %c
719 define i1 @ssub_icmp_op0_neg_known(i8 %a) {
720 ; CHECK-LABEL: @ssub_icmp_op0_neg_known(
721 ; CHECK-NEXT:    ret i1 true
723   %b = call i8 @llvm.ssub.sat.i8(i8 -10, i8 %a)
724   %c = icmp sle i8 %b, 118
725   ret i1 %c
728 define i1 @ssub_icmp_op0_neg_unknown(i8 %a) {
729 ; CHECK-LABEL: @ssub_icmp_op0_neg_unknown(
730 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.ssub.sat.i8(i8 -10, i8 [[A:%.*]])
731 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[B]], 118
732 ; CHECK-NEXT:    ret i1 [[C]]
734   %b = call i8 @llvm.ssub.sat.i8(i8 -10, i8 %a)
735   %c = icmp slt i8 %b, 118
736   ret i1 %c
739 ; Peculiar case: ssub.sat(0, x) is never signed min.
740 define i1 @ssub_icmp_op0_zero(i8 %a) {
741 ; CHECK-LABEL: @ssub_icmp_op0_zero(
742 ; CHECK-NEXT:    ret i1 true
744   %b = call i8 @llvm.ssub.sat.i8(i8 0, i8 %a)
745   %c = icmp ne i8 %b, -128
746   ret i1 %c
749 define i1 @ssub_icmp_op1_pos_known(i8 %a) {
750 ; CHECK-LABEL: @ssub_icmp_op1_pos_known(
751 ; CHECK-NEXT:    ret i1 true
753   %b = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
754   %c = icmp sle i8 %b, 117
755   ret i1 %c
758 define i1 @ssub_icmp_op1_pos_unknown(i8 %a) {
759 ; CHECK-LABEL: @ssub_icmp_op1_pos_unknown(
760 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 10)
761 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[B]], 117
762 ; CHECK-NEXT:    ret i1 [[C]]
764   %b = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
765   %c = icmp slt i8 %b, 117
766   ret i1 %c
769 define i1 @ssub_icmp_op1_neg_known(i8 %a) {
770 ; CHECK-LABEL: @ssub_icmp_op1_neg_known(
771 ; CHECK-NEXT:    ret i1 true
773   %b = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -10)
774   %c = icmp sge i8 %b, -118
775   ret i1 %c
778 define i1 @ssub_icmp_op1_neg_unknown(i8 %a) {
779 ; CHECK-LABEL: @ssub_icmp_op1_neg_unknown(
780 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 -10)
781 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[B]], -118
782 ; CHECK-NEXT:    ret i1 [[C]]
784   %b = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -10)
785   %c = icmp sgt i8 %b, -118
786   ret i1 %c
789 define i1 @ssub_icmp_op1_smin(i8 %a) {
790 ; CHECK-LABEL: @ssub_icmp_op1_smin(
791 ; CHECK-NEXT:    ret i1 true
793   %b = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -128)
794   %c = icmp sge i8 %b, 0
795   ret i1 %c
798 define i1 @uadd_uge(i8 %x, i8 %y) {
799 ; CHECK-LABEL: @uadd_uge(
800 ; CHECK-NEXT:    ret i1 true
802   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
803   %cmp = icmp uge i8 %sat, %x
804   ret i1 %cmp
807 define i1 @uadd_uge_rhs(i8 %x, i8 %y) {
808 ; CHECK-LABEL: @uadd_uge_rhs(
809 ; CHECK-NEXT:    ret i1 true
811   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
812   %cmp = icmp uge i8 %sat, %y
813   ret i1 %cmp
816 define i1 @uadd_uge_commuted(i8 %x, i8 %y) {
817 ; CHECK-LABEL: @uadd_uge_commuted(
818 ; CHECK-NEXT:    ret i1 true
820   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
821   %cmp = icmp ule i8 %x, %sat
822   ret i1 %cmp
825 define i1 @uadd_ult(i8 %x, i8 %y) {
826 ; CHECK-LABEL: @uadd_ult(
827 ; CHECK-NEXT:    ret i1 false
829   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
830   %cmp = icmp ult i8 %sat, %x
831   ret i1 %cmp
834 define <2 x i1> @uadd_uge_vec(<2 x i8> %x, <2 x i8> %y) {
835 ; CHECK-LABEL: @uadd_uge_vec(
836 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
838   %sat = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %x, <2 x i8> %y)
839   %cmp = icmp uge <2 x i8> %sat, %x
840   ret <2 x i1> %cmp
843 define i1 @uadd_ugt_fail(i8 %x, i8 %y) {
844 ; CHECK-LABEL: @uadd_ugt_fail(
845 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
846 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[SAT]], [[X]]
847 ; CHECK-NEXT:    ret i1 [[CMP]]
849   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
850   %cmp = icmp ugt i8 %sat, %x
851   ret i1 %cmp
854 define i1 @uadd_ule_fail(i8 %x, i8 %y) {
855 ; CHECK-LABEL: @uadd_ule_fail(
856 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
857 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[SAT]], [[X]]
858 ; CHECK-NEXT:    ret i1 [[CMP]]
860   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
861   %cmp = icmp ule i8 %sat, %x
862   ret i1 %cmp
865 define i1 @uadd_uge_unrelated_op_fail(i8 %x, i8 %y, i8 %z) {
866 ; CHECK-LABEL: @uadd_uge_unrelated_op_fail(
867 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
868 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[SAT]], [[Z:%.*]]
869 ; CHECK-NEXT:    ret i1 [[CMP]]
871   %sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
872   %cmp = icmp uge i8 %sat, %z
873   ret i1 %cmp
876 define i1 @usub_ule(i8 %x, i8 %y) {
877 ; CHECK-LABEL: @usub_ule(
878 ; CHECK-NEXT:    ret i1 true
880   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
881   %cmp = icmp ule i8 %sat, %x
882   ret i1 %cmp
885 define i1 @usub_ule_rhs_fail(i8 %x, i8 %y) {
886 ; CHECK-LABEL: @usub_ule_rhs_fail(
887 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
888 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[SAT]], [[Y]]
889 ; CHECK-NEXT:    ret i1 [[CMP]]
891   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
892   %cmp = icmp ule i8 %sat, %y
893   ret i1 %cmp
896 define i1 @usub_ule_commuted(i8 %x, i8 %y) {
897 ; CHECK-LABEL: @usub_ule_commuted(
898 ; CHECK-NEXT:    ret i1 true
900   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
901   %cmp = icmp uge i8 %x, %sat
902   ret i1 %cmp
905 define i1 @usub_ugt(i8 %x, i8 %y) {
906 ; CHECK-LABEL: @usub_ugt(
907 ; CHECK-NEXT:    ret i1 false
909   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
910   %cmp = icmp ugt i8 %sat, %x
911   ret i1 %cmp
914 define i1 @usub_ult_fail(i8 %x, i8 %y) {
915 ; CHECK-LABEL: @usub_ult_fail(
916 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
917 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[SAT]], [[X]]
918 ; CHECK-NEXT:    ret i1 [[CMP]]
920   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
921   %cmp = icmp ult i8 %sat, %x
922   ret i1 %cmp
925 define i1 @usub_uge_fail(i8 %x, i8 %y) {
926 ; CHECK-LABEL: @usub_uge_fail(
927 ; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
928 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[SAT]], [[X]]
929 ; CHECK-NEXT:    ret i1 [[CMP]]
931   %sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
932   %cmp = icmp uge i8 %sat, %x
933   ret i1 %cmp