1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4declare i8 @llvm.uadd.sat.i8(i8, i8)
5declare i8 @llvm.sadd.sat.i8(i8, i8)
6declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
7declare <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8>, <2 x i8>)
8
9declare i8 @llvm.usub.sat.i8(i8, i8)
10declare i8 @llvm.ssub.sat.i8(i8, i8)
11declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
12declare <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8>, <2 x i8>)
13
14define i8 @test_uadd_scalar_no_sat() {
15; CHECK-LABEL: @test_uadd_scalar_no_sat(
16; CHECK-NEXT:    ret i8 30
17;
18  %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 20)
19  ret i8 %x
20}
21
22define i8 @test_uadd_scalar_sat() {
23; CHECK-LABEL: @test_uadd_scalar_sat(
24; CHECK-NEXT:    ret i8 -1
25;
26  %x = call i8 @llvm.uadd.sat.i8(i8 250, i8 100)
27  ret i8 %x
28}
29
30define i8 @test_sadd_scalar_no_sat() {
31; CHECK-LABEL: @test_sadd_scalar_no_sat(
32; CHECK-NEXT:    ret i8 -10
33;
34  %x = call i8 @llvm.sadd.sat.i8(i8 10, i8 -20)
35  ret i8 %x
36}
37
38define i8 @test_sadd_scalar_sat_pos() {
39; CHECK-LABEL: @test_sadd_scalar_sat_pos(
40; CHECK-NEXT:    ret i8 127
41;
42  %x = call i8 @llvm.sadd.sat.i8(i8 120, i8 10)
43  ret i8 %x
44}
45
46define i8 @test_sadd_scalar_sat_neg() {
47; CHECK-LABEL: @test_sadd_scalar_sat_neg(
48; CHECK-NEXT:    ret i8 -128
49;
50  %x = call i8 @llvm.sadd.sat.i8(i8 -120, i8 -10)
51  ret i8 %x
52}
53
54define <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>
57;
58  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 15>, <2 x i8> <i8 10, i8 15>)
59  ret <2 x i8> %x
60}
61
62define <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> <i8 -1, i8 -1>
65;
66  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 100, i8 200>, <2 x i8> <i8 250, i8 100>)
67  ret <2 x i8> %x
68}
69
70define <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>
73;
74  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 10, i8 -15>, <2 x i8> <i8 -20, i8 -15>)
75  ret <2 x i8> %x
76}
77
78define <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> <i8 127, i8 127>
81;
82  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 100, i8 10>, <2 x i8> <i8 30, i8 120>)
83  ret <2 x i8> %x
84}
85
86define <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> <i8 -128, i8 -128>
89;
90  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 -100, i8 -10>, <2 x i8> <i8 -30, i8 -120>)
91  ret <2 x i8> %x
92}
93
94define i8 @test_usub_scalar_no_sat() {
95; CHECK-LABEL: @test_usub_scalar_no_sat(
96; CHECK-NEXT:    ret i8 10
97;
98  %x = call i8 @llvm.usub.sat.i8(i8 20, i8 10)
99  ret i8 %x
100}
101
102define i8 @test_usub_scalar_sat() {
103; CHECK-LABEL: @test_usub_scalar_sat(
104; CHECK-NEXT:    ret i8 0
105;
106  %x = call i8 @llvm.usub.sat.i8(i8 200, i8 250)
107  ret i8 %x
108}
109
110define i8 @test_ssub_scalar_no_sat() {
111; CHECK-LABEL: @test_ssub_scalar_no_sat(
112; CHECK-NEXT:    ret i8 -30
113;
114  %x = call i8 @llvm.ssub.sat.i8(i8 -10, i8 20)
115  ret i8 %x
116}
117
118define i8 @test_ssub_scalar_sat_pos() {
119; CHECK-LABEL: @test_ssub_scalar_sat_pos(
120; CHECK-NEXT:    ret i8 127
121;
122  %x = call i8 @llvm.ssub.sat.i8(i8 120, i8 -10)
123  ret i8 %x
124}
125
126define i8 @test_ssub_scalar_sat_neg() {
127; CHECK-LABEL: @test_ssub_scalar_sat_neg(
128; CHECK-NEXT:    ret i8 -128
129;
130  %x = call i8 @llvm.ssub.sat.i8(i8 -120, i8 10)
131  ret i8 %x
132}
133
134define <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>
137;
138  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 20, i8 15>, <2 x i8> <i8 10, i8 10>)
139  ret <2 x i8> %x
140}
141
142define <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
145;
146  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 100, i8 200>, <2 x i8> <i8 150, i8 250>)
147  ret <2 x i8> %x
148}
149
150define <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>
153;
154  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 10, i8 -15>, <2 x i8> <i8 -20, i8 -15>)
155  ret <2 x i8> %x
156}
157
158define <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> <i8 127, i8 127>
161;
162  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 100, i8 10>, <2 x i8> <i8 -30, i8 -120>)
163  ret <2 x i8> %x
164}
165
166define <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> <i8 -128, i8 -128>
169;
170  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 -100, i8 -10>, <2 x i8> <i8 30, i8 120>)
171  ret <2 x i8> %x
172}
173
174; Tests for undef handling
175
176define i8 @test_uadd_scalar_both_undef() {
177; CHECK-LABEL: @test_uadd_scalar_both_undef(
178; CHECK-NEXT:    ret i8 undef
179;
180  %x = call i8 @llvm.uadd.sat.i8(i8 undef, i8 undef)
181  ret i8 %x
182}
183
184define i8 @test_sadd_scalar_both_undef() {
185; CHECK-LABEL: @test_sadd_scalar_both_undef(
186; CHECK-NEXT:    ret i8 undef
187;
188  %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 undef)
189  ret i8 %x
190}
191
192define i8 @test_usub_scalar_both_undef() {
193; CHECK-LABEL: @test_usub_scalar_both_undef(
194; CHECK-NEXT:    ret i8 undef
195;
196  %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 undef)
197  ret i8 %x
198}
199
200define i8 @test_ssub_scalar_both_undef() {
201; CHECK-LABEL: @test_ssub_scalar_both_undef(
202; CHECK-NEXT:    ret i8 undef
203;
204  %x = call i8 @llvm.ssub.sat.i8(i8 undef, i8 undef)
205  ret i8 %x
206}
207
208define i8 @test_uadd_scalar_op2_undef() {
209; CHECK-LABEL: @test_uadd_scalar_op2_undef(
210; CHECK-NEXT:    ret i8 -1
211;
212  %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 undef)
213  ret i8 %x
214}
215
216define i8 @test_sadd_scalar_op1_undef() {
217; CHECK-LABEL: @test_sadd_scalar_op1_undef(
218; CHECK-NEXT:    ret i8 -1
219;
220  %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 10)
221  ret i8 %x
222}
223
224define i8 @test_usub_scalar_op2_undef() {
225; CHECK-LABEL: @test_usub_scalar_op2_undef(
226; CHECK-NEXT:    ret i8 0
227;
228  %x = call i8 @llvm.usub.sat.i8(i8 10, i8 undef)
229  ret i8 %x
230}
231
232define i8 @test_usub_scalar_op1_undef() {
233; CHECK-LABEL: @test_usub_scalar_op1_undef(
234; CHECK-NEXT:    ret i8 0
235;
236  %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 10)
237  ret i8 %x
238}
239
240define <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
243;
244  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
245  ret <2 x i8> %x
246}
247
248define <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
251;
252  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
253  ret <2 x i8> %x
254}
255
256define <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
259;
260  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
261  ret <2 x i8> %x
262}
263
264define <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
267;
268  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
269  ret <2 x i8> %x
270}
271
272define <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> <i8 -1, i8 -1>
275;
276  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
277  ret <2 x i8> %x
278}
279
280define <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> <i8 -1, i8 -1>
283;
284  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
285  ret <2 x i8> %x
286}
287
288define <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
291;
292  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
293  ret <2 x i8> %x
294}
295
296define <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
299;
300  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
301  ret <2 x i8> %x
302}
303
304define <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>
307;
308  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
309  ret <2 x i8> %x
310}
311
312define <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> <i8 -1, i8 -1>
315;
316  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
317  ret <2 x i8> %x
318}
319
320define <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>
323;
324  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
325  ret <2 x i8> %x
326}
327
328define <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> <i8 -1, i8 -1>
331;
332  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
333  ret <2 x i8> %x
334}
335
336define <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>
339;
340  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
341  ret <2 x i8> %x
342}
343
344define <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
347;
348  %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
349  ret <2 x i8> %x
350}
351
352define <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>
355;
356  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
357  ret <2 x i8> %x
358}
359
360define <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
363;
364  %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
365  ret <2 x i8> %x
366}
367