1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 declare i8 @llvm.uadd.sat.i8(i8, i8)
5 declare i8 @llvm.sadd.sat.i8(i8, i8)
6 declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
7 declare <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8>, <2 x i8>)
9 declare i8 @llvm.usub.sat.i8(i8, i8)
10 declare i8 @llvm.ssub.sat.i8(i8, i8)
11 declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
12 declare <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8>, <2 x i8>)
14 define i8 @test_uadd_scalar_no_sat() {
15 ; CHECK-LABEL: @test_uadd_scalar_no_sat(
16 ; CHECK-NEXT: ret i8 30
18 %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 20)
22 define i8 @test_uadd_scalar_sat() {
23 ; CHECK-LABEL: @test_uadd_scalar_sat(
24 ; CHECK-NEXT: ret i8 -1
26 %x = call i8 @llvm.uadd.sat.i8(i8 250, i8 100)
30 define i8 @test_sadd_scalar_no_sat() {
31 ; CHECK-LABEL: @test_sadd_scalar_no_sat(
32 ; CHECK-NEXT: ret i8 -10
34 %x = call i8 @llvm.sadd.sat.i8(i8 10, i8 -20)
38 define i8 @test_sadd_scalar_sat_pos() {
39 ; CHECK-LABEL: @test_sadd_scalar_sat_pos(
40 ; CHECK-NEXT: ret i8 127
42 %x = call i8 @llvm.sadd.sat.i8(i8 120, i8 10)
46 define i8 @test_sadd_scalar_sat_neg() {
47 ; CHECK-LABEL: @test_sadd_scalar_sat_neg(
48 ; CHECK-NEXT: ret i8 -128
50 %x = call i8 @llvm.sadd.sat.i8(i8 -120, i8 -10)
54 define <2 x i8> @test_uadd_vector_no_sat(<2 x i8> %a) {
55 ; CHECK-LABEL: @test_uadd_vector_no_sat(
56 ; CHECK-NEXT: ret <2 x i8> <i8 20, i8 30>
58 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 15>, <2 x i8> <i8 10, i8 15>)
62 define <2 x i8> @test_uadd_vector_sat(<2 x i8> %a) {
63 ; CHECK-LABEL: @test_uadd_vector_sat(
64 ; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
66 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 100, i8 200>, <2 x i8> <i8 250, i8 100>)
70 define <2 x i8> @test_sadd_vector_no_sat(<2 x i8> %a) {
71 ; CHECK-LABEL: @test_sadd_vector_no_sat(
72 ; CHECK-NEXT: ret <2 x i8> <i8 -10, i8 -30>
74 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 10, i8 -15>, <2 x i8> <i8 -20, i8 -15>)
78 define <2 x i8> @test_sadd_vector_sat_pos(<2 x i8> %a) {
79 ; CHECK-LABEL: @test_sadd_vector_sat_pos(
80 ; CHECK-NEXT: ret <2 x i8> splat (i8 127)
82 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 100, i8 10>, <2 x i8> <i8 30, i8 120>)
86 define <2 x i8> @test_sadd_vector_sat_neg(<2 x i8> %a) {
87 ; CHECK-LABEL: @test_sadd_vector_sat_neg(
88 ; CHECK-NEXT: ret <2 x i8> splat (i8 -128)
90 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 -100, i8 -10>, <2 x i8> <i8 -30, i8 -120>)
94 define i8 @test_usub_scalar_no_sat() {
95 ; CHECK-LABEL: @test_usub_scalar_no_sat(
96 ; CHECK-NEXT: ret i8 10
98 %x = call i8 @llvm.usub.sat.i8(i8 20, i8 10)
102 define i8 @test_usub_scalar_sat() {
103 ; CHECK-LABEL: @test_usub_scalar_sat(
104 ; CHECK-NEXT: ret i8 0
106 %x = call i8 @llvm.usub.sat.i8(i8 200, i8 250)
110 define i8 @test_ssub_scalar_no_sat() {
111 ; CHECK-LABEL: @test_ssub_scalar_no_sat(
112 ; CHECK-NEXT: ret i8 -30
114 %x = call i8 @llvm.ssub.sat.i8(i8 -10, i8 20)
118 define i8 @test_ssub_scalar_sat_pos() {
119 ; CHECK-LABEL: @test_ssub_scalar_sat_pos(
120 ; CHECK-NEXT: ret i8 127
122 %x = call i8 @llvm.ssub.sat.i8(i8 120, i8 -10)
126 define i8 @test_ssub_scalar_sat_neg() {
127 ; CHECK-LABEL: @test_ssub_scalar_sat_neg(
128 ; CHECK-NEXT: ret i8 -128
130 %x = call i8 @llvm.ssub.sat.i8(i8 -120, i8 10)
134 define <2 x i8> @test_usub_vector_no_sat(<2 x i8> %a) {
135 ; CHECK-LABEL: @test_usub_vector_no_sat(
136 ; CHECK-NEXT: ret <2 x i8> <i8 10, i8 5>
138 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 20, i8 15>, <2 x i8> <i8 10, i8 10>)
142 define <2 x i8> @test_usub_vector_sat(<2 x i8> %a) {
143 ; CHECK-LABEL: @test_usub_vector_sat(
144 ; CHECK-NEXT: ret <2 x i8> zeroinitializer
146 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 100, i8 200>, <2 x i8> <i8 150, i8 250>)
150 define <2 x i8> @test_ssub_vector_no_sat(<2 x i8> %a) {
151 ; CHECK-LABEL: @test_ssub_vector_no_sat(
152 ; CHECK-NEXT: ret <2 x i8> <i8 30, i8 0>
154 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 10, i8 -15>, <2 x i8> <i8 -20, i8 -15>)
158 define <2 x i8> @test_ssub_vector_sat_pos(<2 x i8> %a) {
159 ; CHECK-LABEL: @test_ssub_vector_sat_pos(
160 ; CHECK-NEXT: ret <2 x i8> splat (i8 127)
162 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 100, i8 10>, <2 x i8> <i8 -30, i8 -120>)
166 define <2 x i8> @test_ssub_vector_sat_neg(<2 x i8> %a) {
167 ; CHECK-LABEL: @test_ssub_vector_sat_neg(
168 ; CHECK-NEXT: ret <2 x i8> splat (i8 -128)
170 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 -100, i8 -10>, <2 x i8> <i8 30, i8 120>)
174 ; Tests for undef handling
176 define i8 @test_uadd_scalar_both_undef() {
177 ; CHECK-LABEL: @test_uadd_scalar_both_undef(
178 ; CHECK-NEXT: ret i8 undef
180 %x = call i8 @llvm.uadd.sat.i8(i8 undef, i8 undef)
184 define i8 @test_sadd_scalar_both_undef() {
185 ; CHECK-LABEL: @test_sadd_scalar_both_undef(
186 ; CHECK-NEXT: ret i8 undef
188 %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 undef)
192 define i8 @test_usub_scalar_both_undef() {
193 ; CHECK-LABEL: @test_usub_scalar_both_undef(
194 ; CHECK-NEXT: ret i8 undef
196 %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 undef)
200 define i8 @test_ssub_scalar_both_undef() {
201 ; CHECK-LABEL: @test_ssub_scalar_both_undef(
202 ; CHECK-NEXT: ret i8 undef
204 %x = call i8 @llvm.ssub.sat.i8(i8 undef, i8 undef)
208 define i8 @test_uadd_scalar_op2_undef() {
209 ; CHECK-LABEL: @test_uadd_scalar_op2_undef(
210 ; CHECK-NEXT: ret i8 -1
212 %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 undef)
216 define i8 @test_sadd_scalar_op1_undef() {
217 ; CHECK-LABEL: @test_sadd_scalar_op1_undef(
218 ; CHECK-NEXT: ret i8 -1
220 %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 10)
224 define i8 @test_usub_scalar_op2_undef() {
225 ; CHECK-LABEL: @test_usub_scalar_op2_undef(
226 ; CHECK-NEXT: ret i8 0
228 %x = call i8 @llvm.usub.sat.i8(i8 10, i8 undef)
232 define i8 @test_usub_scalar_op1_undef() {
233 ; CHECK-LABEL: @test_usub_scalar_op1_undef(
234 ; CHECK-NEXT: ret i8 0
236 %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 10)
240 define <2 x i8> @test_uadd_vector_both_undef_splat() {
241 ; CHECK-LABEL: @test_uadd_vector_both_undef_splat(
242 ; CHECK-NEXT: ret <2 x i8> undef
244 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
248 define <2 x i8> @test_sadd_vector_both_undef_splat() {
249 ; CHECK-LABEL: @test_sadd_vector_both_undef_splat(
250 ; CHECK-NEXT: ret <2 x i8> undef
252 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
256 define <2 x i8> @test_usub_vector_both_undef_splat() {
257 ; CHECK-LABEL: @test_usub_vector_both_undef_splat(
258 ; CHECK-NEXT: ret <2 x i8> undef
260 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
264 define <2 x i8> @test_ssub_vector_both_undef_splat() {
265 ; CHECK-LABEL: @test_ssub_vector_both_undef_splat(
266 ; CHECK-NEXT: ret <2 x i8> undef
268 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
272 define <2 x i8> @test_uadd_vector_op2_undef_splat() {
273 ; CHECK-LABEL: @test_uadd_vector_op2_undef_splat(
274 ; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
276 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
280 define <2 x i8> @test_sadd_vector_op1_undef_splat() {
281 ; CHECK-LABEL: @test_sadd_vector_op1_undef_splat(
282 ; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
284 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
288 define <2 x i8> @test_usub_vector_op2_undef_splat() {
289 ; CHECK-LABEL: @test_usub_vector_op2_undef_splat(
290 ; CHECK-NEXT: ret <2 x i8> zeroinitializer
292 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
296 define <2 x i8> @test_ssub_vector_op1_undef_splat() {
297 ; CHECK-LABEL: @test_ssub_vector_op1_undef_splat(
298 ; CHECK-NEXT: ret <2 x i8> zeroinitializer
300 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
304 define <2 x i8> @test_uadd_vector_op2_undef_mix1() {
305 ; CHECK-LABEL: @test_uadd_vector_op2_undef_mix1(
306 ; CHECK-NEXT: ret <2 x i8> <i8 30, i8 undef>
308 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
312 define <2 x i8> @test_uadd_vector_op2_undef_mix2() {
313 ; CHECK-LABEL: @test_uadd_vector_op2_undef_mix2(
314 ; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
316 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
320 define <2 x i8> @test_sadd_vector_op1_undef_mix1() {
321 ; CHECK-LABEL: @test_sadd_vector_op1_undef_mix1(
322 ; CHECK-NEXT: ret <2 x i8> <i8 undef, i8 30>
324 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
328 define <2 x i8> @test_sadd_vector_op1_undef_mix2() {
329 ; CHECK-LABEL: @test_sadd_vector_op1_undef_mix2(
330 ; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
332 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
336 define <2 x i8> @test_usub_vector_op2_undef_mix1() {
337 ; CHECK-LABEL: @test_usub_vector_op2_undef_mix1(
338 ; CHECK-NEXT: ret <2 x i8> <i8 0, i8 undef>
340 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
344 define <2 x i8> @test_usub_vector_op2_undef_mix2() {
345 ; CHECK-LABEL: @test_usub_vector_op2_undef_mix2(
346 ; CHECK-NEXT: ret <2 x i8> zeroinitializer
348 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
352 define <2 x i8> @test_ssub_vector_op1_undef_mix1() {
353 ; CHECK-LABEL: @test_ssub_vector_op1_undef_mix1(
354 ; CHECK-NEXT: ret <2 x i8> <i8 undef, i8 -10>
356 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
360 define <2 x i8> @test_ssub_vector_op1_undef_mix2() {
361 ; CHECK-LABEL: @test_ssub_vector_op1_undef_mix2(
362 ; CHECK-NEXT: ret <2 x i8> zeroinitializer
364 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
368 ; Tests for poison handling
370 define i8 @test_uadd_scalar_both_poison() {
371 ; CHECK-LABEL: @test_uadd_scalar_both_poison(
372 ; CHECK-NEXT: ret i8 poison
374 %x = call i8 @llvm.uadd.sat.i8(i8 poison, i8 poison)
378 define i8 @test_sadd_scalar_both_poison() {
379 ; CHECK-LABEL: @test_sadd_scalar_both_poison(
380 ; CHECK-NEXT: ret i8 poison
382 %x = call i8 @llvm.sadd.sat.i8(i8 poison, i8 poison)
386 define i8 @test_usub_scalar_both_poison() {
387 ; CHECK-LABEL: @test_usub_scalar_both_poison(
388 ; CHECK-NEXT: ret i8 poison
390 %x = call i8 @llvm.usub.sat.i8(i8 poison, i8 poison)
394 define i8 @test_ssub_scalar_both_poison() {
395 ; CHECK-LABEL: @test_ssub_scalar_both_poison(
396 ; CHECK-NEXT: ret i8 poison
398 %x = call i8 @llvm.ssub.sat.i8(i8 poison, i8 poison)
402 define i8 @test_uadd_scalar_op2_poison() {
403 ; CHECK-LABEL: @test_uadd_scalar_op2_poison(
404 ; CHECK-NEXT: ret i8 poison
406 %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 poison)
410 define i8 @test_sadd_scalar_op1_poison() {
411 ; CHECK-LABEL: @test_sadd_scalar_op1_poison(
412 ; CHECK-NEXT: ret i8 poison
414 %x = call i8 @llvm.sadd.sat.i8(i8 poison, i8 10)
418 define i8 @test_usub_scalar_op2_poison() {
419 ; CHECK-LABEL: @test_usub_scalar_op2_poison(
420 ; CHECK-NEXT: ret i8 poison
422 %x = call i8 @llvm.usub.sat.i8(i8 10, i8 poison)
426 define i8 @test_usub_scalar_op1_poison() {
427 ; CHECK-LABEL: @test_usub_scalar_op1_poison(
428 ; CHECK-NEXT: ret i8 poison
430 %x = call i8 @llvm.usub.sat.i8(i8 poison, i8 10)
434 define <2 x i8> @test_uadd_vector_both_poison_splat() {
435 ; CHECK-LABEL: @test_uadd_vector_both_poison_splat(
436 ; CHECK-NEXT: ret <2 x i8> poison
438 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
442 define <2 x i8> @test_sadd_vector_both_poison_splat() {
443 ; CHECK-LABEL: @test_sadd_vector_both_poison_splat(
444 ; CHECK-NEXT: ret <2 x i8> poison
446 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
450 define <2 x i8> @test_usub_vector_both_poison_splat() {
451 ; CHECK-LABEL: @test_usub_vector_both_poison_splat(
452 ; CHECK-NEXT: ret <2 x i8> poison
454 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
458 define <2 x i8> @test_ssub_vector_both_poison_splat() {
459 ; CHECK-LABEL: @test_ssub_vector_both_poison_splat(
460 ; CHECK-NEXT: ret <2 x i8> poison
462 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
466 define <2 x i8> @test_uadd_vector_op2_poison_splat() {
467 ; CHECK-LABEL: @test_uadd_vector_op2_poison_splat(
468 ; CHECK-NEXT: ret <2 x i8> poison
470 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> poison)
474 define <2 x i8> @test_sadd_vector_op1_poison_splat() {
475 ; CHECK-LABEL: @test_sadd_vector_op1_poison_splat(
476 ; CHECK-NEXT: ret <2 x i8> poison
478 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> <i8 10, i8 20>)
482 define <2 x i8> @test_usub_vector_op2_poison_splat() {
483 ; CHECK-LABEL: @test_usub_vector_op2_poison_splat(
484 ; CHECK-NEXT: ret <2 x i8> poison
486 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> poison)
490 define <2 x i8> @test_ssub_vector_op1_poison_splat() {
491 ; CHECK-LABEL: @test_ssub_vector_op1_poison_splat(
492 ; CHECK-NEXT: ret <2 x i8> poison
494 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> poison, <2 x i8> <i8 10, i8 20>)
498 define <2 x i8> @test_uadd_vector_op2_poison_mix1() {
499 ; CHECK-LABEL: @test_uadd_vector_op2_poison_mix1(
500 ; CHECK-NEXT: ret <2 x i8> <i8 30, i8 poison>
502 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 20, i8 poison>)
506 define <2 x i8> @test_uadd_vector_op2_poison_mix2() {
507 ; CHECK-LABEL: @test_uadd_vector_op2_poison_mix2(
508 ; CHECK-NEXT: ret <2 x i8> poison
510 %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 poison, i8 20>)
514 define <2 x i8> @test_sadd_vector_op1_poison_mix1() {
515 ; CHECK-LABEL: @test_sadd_vector_op1_poison_mix1(
516 ; CHECK-NEXT: ret <2 x i8> <i8 poison, i8 30>
518 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 poison, i8 20>)
522 define <2 x i8> @test_sadd_vector_op1_poison_mix2() {
523 ; CHECK-LABEL: @test_sadd_vector_op1_poison_mix2(
524 ; CHECK-NEXT: ret <2 x i8> poison
526 %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 20, i8 poison>)
530 define <2 x i8> @test_usub_vector_op2_poison_mix1() {
531 ; CHECK-LABEL: @test_usub_vector_op2_poison_mix1(
532 ; CHECK-NEXT: ret <2 x i8> <i8 0, i8 poison>
534 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 20, i8 poison>)
538 define <2 x i8> @test_usub_vector_op2_poison_mix2() {
539 ; CHECK-LABEL: @test_usub_vector_op2_poison_mix2(
540 ; CHECK-NEXT: ret <2 x i8> poison
542 %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 poison, i8 20>)
546 define <2 x i8> @test_ssub_vector_op1_poison_mix1() {
547 ; CHECK-LABEL: @test_ssub_vector_op1_poison_mix1(
548 ; CHECK-NEXT: ret <2 x i8> <i8 poison, i8 -10>
550 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 poison, i8 20>)
554 define <2 x i8> @test_ssub_vector_op1_poison_mix2() {
555 ; CHECK-LABEL: @test_ssub_vector_op1_poison_mix2(
556 ; CHECK-NEXT: ret <2 x i8> poison
558 %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 20, i8 poison>)