[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Analysis / ConstantFolding / saturating-add-sub.ll
blob7c6fdbf1e1fd152543e369172e56cd466e3c8131
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -constprop -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)
19   ret i8 %x
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)
27   ret i8 %x
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)
35   ret i8 %x
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)
43   ret i8 %x
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)
51   ret i8 %x
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>)
59   ret <2 x i8> %x
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> <i8 -1, 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>)
67   ret <2 x i8> %x
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>)
75   ret <2 x i8> %x
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> <i8 127, 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>)
83   ret <2 x i8> %x
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> <i8 -128, 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>)
91   ret <2 x i8> %x
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)
99   ret i8 %x
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)
107   ret i8 %x
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)
115   ret i8 %x
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)
123   ret i8 %x
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)
131   ret i8 %x
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>)
139   ret <2 x i8> %x
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>)
147   ret <2 x i8> %x
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>)
155   ret <2 x i8> %x
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> <i8 127, 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>)
163   ret <2 x i8> %x
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> <i8 -128, 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>)
171   ret <2 x i8> %x
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)
181   ret i8 %x
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)
189   ret i8 %x
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)
197   ret i8 %x
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)
205   ret i8 %x
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)
213   ret i8 %x
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)
221   ret i8 %x
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)
229   ret i8 %x
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)
237   ret i8 %x
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)
245   ret <2 x i8> %x
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)
253   ret <2 x i8> %x
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)
261   ret <2 x i8> %x
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)
269   ret <2 x i8> %x
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> <i8 -1, i8 -1>
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
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> <i8 -1, i8 -1>
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
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)
293   ret <2 x i8> %x
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>)
301   ret <2 x i8> %x
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>)
309   ret <2 x i8> %x
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> <i8 -1, 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>)
317   ret <2 x i8> %x
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>)
325   ret <2 x i8> %x
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> <i8 -1, 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>)
333   ret <2 x i8> %x
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>)
341   ret <2 x i8> %x
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>)
349   ret <2 x i8> %x
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>)
357   ret <2 x i8> %x
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>)
365   ret <2 x i8> %x