xref: /llvm-project/llvm/test/Transforms/InstCombine/saturating-add-sub.ll (revision 979a0356d4c90ec855be4f2d2f6687132cf10298)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4;
5; Saturating addition.
6;
7
8declare i8 @llvm.uadd.sat.i8(i8, i8)
9declare i8 @llvm.sadd.sat.i8(i8, i8)
10declare <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8>, <2 x i8>)
11declare <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8>, <2 x i8>)
12
13; Constant uadd argument is canonicalized to the right.
14define i8 @test_scalar_uadd_canonical(i8 %a) {
15; CHECK-LABEL: @test_scalar_uadd_canonical(
16; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 10)
17; CHECK-NEXT:    ret i8 [[X]]
18;
19  %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 %a)
20  ret i8 %x
21}
22
23define <2 x i8> @test_vector_uadd_canonical(<2 x i8> %a) {
24; CHECK-LABEL: @test_vector_uadd_canonical(
25; CHECK-NEXT:    [[X:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 20>)
26; CHECK-NEXT:    ret <2 x i8> [[X]]
27;
28  %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> %a)
29  ret <2 x i8> %x
30}
31
32; Constant sadd argument is canonicalized to the right.
33define i8 @test_scalar_sadd_canonical(i8 %a) {
34; CHECK-LABEL: @test_scalar_sadd_canonical(
35; CHECK-NEXT:    [[X:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
36; CHECK-NEXT:    ret i8 [[X]]
37;
38  %x = call i8 @llvm.sadd.sat.i8(i8 -10, i8 %a)
39  ret i8 %x
40}
41
42define <2 x i8> @test_vector_sadd_canonical(<2 x i8> %a) {
43; CHECK-LABEL: @test_vector_sadd_canonical(
44; CHECK-NEXT:    [[X:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 -20>)
45; CHECK-NEXT:    ret <2 x i8> [[X]]
46;
47  %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 10, i8 -20>, <2 x i8> %a)
48  ret <2 x i8> %x
49}
50
51; Can combine uadds with constant operands.
52define i8 @test_scalar_uadd_combine(i8 %a) {
53; CHECK-LABEL: @test_scalar_uadd_combine(
54; CHECK-NEXT:    [[X2:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 30)
55; CHECK-NEXT:    ret i8 [[X2]]
56;
57  %x1 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 10)
58  %x2 = call i8 @llvm.uadd.sat.i8(i8 %x1, i8 20)
59  ret i8 %x2
60}
61
62define <2 x i8> @test_vector_uadd_combine(<2 x i8> %a) {
63; CHECK-LABEL: @test_vector_uadd_combine(
64; CHECK-NEXT:    [[X2:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 30))
65; CHECK-NEXT:    ret <2 x i8> [[X2]]
66;
67  %x1 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
68  %x2 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %x1, <2 x i8> <i8 20, i8 20>)
69  ret <2 x i8> %x2
70}
71
72; This could simplify, but currently doesn't.
73define <2 x i8> @test_vector_uadd_combine_non_splat(<2 x i8> %a) {
74; CHECK-LABEL: @test_vector_uadd_combine_non_splat(
75; CHECK-NEXT:    [[X1:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 20>)
76; CHECK-NEXT:    [[X2:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X1]], <2 x i8> <i8 30, i8 40>)
77; CHECK-NEXT:    ret <2 x i8> [[X2]]
78;
79  %x1 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 20>)
80  %x2 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %x1, <2 x i8> <i8 30, i8 40>)
81  ret <2 x i8> %x2
82}
83
84; Can combine uadds even if they overflow.
85define i8 @test_scalar_uadd_overflow(i8 %a) {
86; CHECK-LABEL: @test_scalar_uadd_overflow(
87; CHECK-NEXT:    ret i8 -1
88;
89  %y1 = call i8 @llvm.uadd.sat.i8(i8 %a, i8 100)
90  %y2 = call i8 @llvm.uadd.sat.i8(i8 %y1, i8 200)
91  ret i8 %y2
92}
93
94define <2 x i8> @test_vector_uadd_overflow(<2 x i8> %a) {
95; CHECK-LABEL: @test_vector_uadd_overflow(
96; CHECK-NEXT:    ret <2 x i8> splat (i8 -1)
97;
98  %y1 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 100, i8 100>)
99  %y2 = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %y1, <2 x i8> <i8 200, i8 200>)
100  ret <2 x i8> %y2
101}
102
103; Can combine sadds if sign matches.
104define i8 @test_scalar_sadd_both_positive(i8 %a) {
105; CHECK-LABEL: @test_scalar_sadd_both_positive(
106; CHECK-NEXT:    [[Z2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 30)
107; CHECK-NEXT:    ret i8 [[Z2]]
108;
109  %z1 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 10)
110  %z2 = call i8 @llvm.sadd.sat.i8(i8 %z1, i8 20)
111  ret i8 %z2
112}
113
114define <2 x i8> @test_vector_sadd_both_positive(<2 x i8> %a) {
115; CHECK-LABEL: @test_vector_sadd_both_positive(
116; CHECK-NEXT:    [[Z2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 30))
117; CHECK-NEXT:    ret <2 x i8> [[Z2]]
118;
119  %z1 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
120  %z2 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %z1, <2 x i8> <i8 20, i8 20>)
121  ret <2 x i8> %z2
122}
123
124define i8 @test_scalar_sadd_both_negative(i8 %a) {
125; CHECK-LABEL: @test_scalar_sadd_both_negative(
126; CHECK-NEXT:    [[U2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -30)
127; CHECK-NEXT:    ret i8 [[U2]]
128;
129  %u1 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 -10)
130  %u2 = call i8 @llvm.sadd.sat.i8(i8 %u1, i8 -20)
131  ret i8 %u2
132}
133
134define <2 x i8> @test_vector_sadd_both_negative(<2 x i8> %a) {
135; CHECK-LABEL: @test_vector_sadd_both_negative(
136; CHECK-NEXT:    [[U2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 -30))
137; CHECK-NEXT:    ret <2 x i8> [[U2]]
138;
139  %u1 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 -10, i8 -10>)
140  %u2 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %u1, <2 x i8> <i8 -20, i8 -20>)
141  ret <2 x i8> %u2
142}
143
144; Can't combine sadds if constants have different sign.
145define i8 @test_scalar_sadd_different_sign(i8 %a) {
146; CHECK-LABEL: @test_scalar_sadd_different_sign(
147; CHECK-NEXT:    [[V1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 10)
148; CHECK-NEXT:    [[V2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[V1]], i8 -20)
149; CHECK-NEXT:    ret i8 [[V2]]
150;
151  %v1 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 10)
152  %v2 = call i8 @llvm.sadd.sat.i8(i8 %v1, i8 -20)
153  ret i8 %v2
154}
155
156; Can't combine sadds if they overflow.
157define i8 @test_scalar_sadd_overflow(i8 %a) {
158; CHECK-LABEL: @test_scalar_sadd_overflow(
159; CHECK-NEXT:    [[W1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 100)
160; CHECK-NEXT:    [[W2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[W1]], i8 100)
161; CHECK-NEXT:    ret i8 [[W2]]
162;
163  %w1 = call i8 @llvm.sadd.sat.i8(i8 %a, i8 100)
164  %w2 = call i8 @llvm.sadd.sat.i8(i8 %w1, i8 100)
165  ret i8 %w2
166}
167
168; neg uadd neg always overflows.
169define i8 @test_scalar_uadd_neg_neg(i8 %a) {
170; CHECK-LABEL: @test_scalar_uadd_neg_neg(
171; CHECK-NEXT:    ret i8 -1
172;
173  %a_neg = or i8 %a, -128
174  %r = call i8 @llvm.uadd.sat.i8(i8 %a_neg, i8 -10)
175  ret i8 %r
176}
177
178define <2 x i8> @test_vector_uadd_neg_neg(<2 x i8> %a) {
179; CHECK-LABEL: @test_vector_uadd_neg_neg(
180; CHECK-NEXT:    ret <2 x i8> splat (i8 -1)
181;
182  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
183  %r = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 -10, i8 -20>)
184  ret <2 x i8> %r
185}
186
187; nneg uadd nneg never overflows.
188define i8 @test_scalar_uadd_nneg_nneg(i8 %a) {
189; CHECK-LABEL: @test_scalar_uadd_nneg_nneg(
190; CHECK-NEXT:    [[A_NNEG:%.*]] = and i8 [[A:%.*]], 127
191; CHECK-NEXT:    [[R:%.*]] = add nuw i8 [[A_NNEG]], 10
192; CHECK-NEXT:    ret i8 [[R]]
193;
194  %a_nneg = and i8 %a, 127
195  %r = call i8 @llvm.uadd.sat.i8(i8 %a_nneg, i8 10)
196  ret i8 %r
197}
198
199define <2 x i8> @test_vector_uadd_nneg_nneg(<2 x i8> %a) {
200; CHECK-LABEL: @test_vector_uadd_nneg_nneg(
201; CHECK-NEXT:    [[A_NNEG:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 127)
202; CHECK-NEXT:    [[R:%.*]] = add nuw <2 x i8> [[A_NNEG]], <i8 10, i8 20>
203; CHECK-NEXT:    ret <2 x i8> [[R]]
204;
205  %a_nneg = and <2 x i8> %a, <i8 127, i8 127>
206  %r = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a_nneg, <2 x i8> <i8 10, i8 20>)
207  ret <2 x i8> %r
208}
209
210; neg uadd nneg might overflow.
211define i8 @test_scalar_uadd_neg_nneg(i8 %a) {
212; CHECK-LABEL: @test_scalar_uadd_neg_nneg(
213; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
214; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A_NEG]], i8 10)
215; CHECK-NEXT:    ret i8 [[R]]
216;
217  %a_neg = or i8 %a, -128
218  %r = call i8 @llvm.uadd.sat.i8(i8 %a_neg, i8 10)
219  ret i8 %r
220}
221
222define <2 x i8> @test_vector_uadd_neg_nneg(<2 x i8> %a) {
223; CHECK-LABEL: @test_vector_uadd_neg_nneg(
224; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
225; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A_NEG]], <2 x i8> <i8 10, i8 20>)
226; CHECK-NEXT:    ret <2 x i8> [[R]]
227;
228  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
229  %r = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 10, i8 20>)
230  ret <2 x i8> %r
231}
232
233define i8 @test_scalar_uadd_never_overflows(i8 %a) {
234; CHECK-LABEL: @test_scalar_uadd_never_overflows(
235; CHECK-NEXT:    [[A_MASKED:%.*]] = and i8 [[A:%.*]], -127
236; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[A_MASKED]], 1
237; CHECK-NEXT:    ret i8 [[R]]
238;
239  %a_masked = and i8 %a, 129
240  %r = call i8 @llvm.uadd.sat.i8(i8 %a_masked, i8 1)
241  ret i8 %r
242}
243
244define <2 x i8> @test_vector_uadd_never_overflows(<2 x i8> %a) {
245; CHECK-LABEL: @test_vector_uadd_never_overflows(
246; CHECK-NEXT:    [[A_MASKED:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 -127)
247; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i8> [[A_MASKED]], splat (i8 1)
248; CHECK-NEXT:    ret <2 x i8> [[R]]
249;
250  %a_masked = and <2 x i8> %a, <i8 129, i8 129>
251  %r = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a_masked, <2 x i8> <i8 1, i8 1>)
252  ret <2 x i8> %r
253}
254
255define i8 @test_scalar_uadd_always_overflows(i8 %a) {
256; CHECK-LABEL: @test_scalar_uadd_always_overflows(
257; CHECK-NEXT:    ret i8 -1
258;
259  %a_masked = or i8 %a, 192
260  %r = call i8 @llvm.uadd.sat.i8(i8 %a_masked, i8 64)
261  ret i8 %r
262}
263
264define <2 x i8> @test_vector_uadd_always_overflows(<2 x i8> %a) {
265; CHECK-LABEL: @test_vector_uadd_always_overflows(
266; CHECK-NEXT:    ret <2 x i8> splat (i8 -1)
267;
268  %a_masked = or <2 x i8> %a, <i8 192, i8 192>
269  %r = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a_masked, <2 x i8> <i8 64, i8 64>)
270  ret <2 x i8> %r
271}
272
273; neg sadd nneg never overflows.
274define i8 @test_scalar_sadd_neg_nneg(i8 %a) {
275; CHECK-LABEL: @test_scalar_sadd_neg_nneg(
276; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
277; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A_NEG]], 10
278; CHECK-NEXT:    ret i8 [[R]]
279;
280  %a_neg = or i8 %a, -128
281  %r = call i8 @llvm.sadd.sat.i8(i8 %a_neg, i8 10)
282  ret i8 %r
283}
284
285define <2 x i8> @test_vector_sadd_neg_nneg(<2 x i8> %a) {
286; CHECK-LABEL: @test_vector_sadd_neg_nneg(
287; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
288; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[A_NEG]], <i8 10, i8 20>
289; CHECK-NEXT:    ret <2 x i8> [[R]]
290;
291  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
292  %r = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 10, i8 20>)
293  ret <2 x i8> %r
294}
295
296; nneg sadd neg never overflows.
297define i8 @test_scalar_sadd_nneg_neg(i8 %a) {
298; CHECK-LABEL: @test_scalar_sadd_nneg_neg(
299; CHECK-NEXT:    [[A_NNEG:%.*]] = and i8 [[A:%.*]], 127
300; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A_NNEG]], -10
301; CHECK-NEXT:    ret i8 [[R]]
302;
303  %a_nneg = and i8 %a, 127
304  %r = call i8 @llvm.sadd.sat.i8(i8 %a_nneg, i8 -10)
305  ret i8 %r
306}
307
308define <2 x i8> @test_vector_sadd_nneg_neg(<2 x i8> %a) {
309; CHECK-LABEL: @test_vector_sadd_nneg_neg(
310; CHECK-NEXT:    [[A_NNEG:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 127)
311; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[A_NNEG]], <i8 -10, i8 -20>
312; CHECK-NEXT:    ret <2 x i8> [[R]]
313;
314  %a_nneg = and <2 x i8> %a, <i8 127, i8 127>
315  %r = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a_nneg, <2 x i8> <i8 -10, i8 -20>)
316  ret <2 x i8> %r
317}
318
319; neg sadd neg might overflow.
320define i8 @test_scalar_sadd_neg_neg(i8 %a) {
321; CHECK-LABEL: @test_scalar_sadd_neg_neg(
322; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
323; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A_NEG]], i8 -10)
324; CHECK-NEXT:    ret i8 [[R]]
325;
326  %a_neg = or i8 %a, -128
327  %r = call i8 @llvm.sadd.sat.i8(i8 %a_neg, i8 -10)
328  ret i8 %r
329}
330
331define <2 x i8> @test_vector_sadd_neg_neg(<2 x i8> %a) {
332; CHECK-LABEL: @test_vector_sadd_neg_neg(
333; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
334; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A_NEG]], <2 x i8> <i8 -10, i8 -20>)
335; CHECK-NEXT:    ret <2 x i8> [[R]]
336;
337  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
338  %r = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 -10, i8 -20>)
339  ret <2 x i8> %r
340}
341
342define i8 @test_scalar_sadd_always_overflows_low(i8 %a) {
343; CHECK-LABEL: @test_scalar_sadd_always_overflows_low(
344; CHECK-NEXT:    ret i8 -128
345;
346  %cmp = icmp slt i8 %a, -120
347  %min = select i1 %cmp, i8 %a, i8 -120
348  %r = call i8 @llvm.sadd.sat.i8(i8 %min, i8 -10)
349  ret i8 %r
350}
351
352define i8 @test_scalar_sadd_always_overflows_high(i8 %a) {
353; CHECK-LABEL: @test_scalar_sadd_always_overflows_high(
354; CHECK-NEXT:    ret i8 127
355;
356  %cmp = icmp sgt i8 %a, 120
357  %max = select i1 %cmp, i8 %a, i8 120
358  %r = call i8 @llvm.sadd.sat.i8(i8 %max, i8 10)
359  ret i8 %r
360}
361
362; While this is a no-overflow condition, the nuw flag gets lost due to
363; canonicalization and we can no longer determine this
364define i8 @test_scalar_uadd_sub_nuw_lost_no_ov(i8 %a) {
365; CHECK-LABEL: @test_scalar_uadd_sub_nuw_lost_no_ov(
366; CHECK-NEXT:    [[B:%.*]] = add i8 [[A:%.*]], -10
367; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[B]], i8 9)
368; CHECK-NEXT:    ret i8 [[R]]
369;
370  %b = sub nuw i8 %a, 10
371  %r = call i8 @llvm.uadd.sat.i8(i8 %b, i8 9)
372  ret i8 %r
373}
374
375define i8 @test_scalar_uadd_urem_no_ov(i8 %a) {
376; CHECK-LABEL: @test_scalar_uadd_urem_no_ov(
377; CHECK-NEXT:    [[B:%.*]] = urem i8 [[A:%.*]], 100
378; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[B]], -100
379; CHECK-NEXT:    ret i8 [[R]]
380;
381  %b = urem i8 %a, 100
382  %r = call i8 @llvm.uadd.sat.i8(i8 %b, i8 156)
383  ret i8 %r
384}
385
386define i8 @test_scalar_uadd_urem_may_ov(i8 %a) {
387; CHECK-LABEL: @test_scalar_uadd_urem_may_ov(
388; CHECK-NEXT:    [[B:%.*]] = urem i8 [[A:%.*]], 100
389; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[B]], i8 -99)
390; CHECK-NEXT:    ret i8 [[R]]
391;
392  %b = urem i8 %a, 100
393  %r = call i8 @llvm.uadd.sat.i8(i8 %b, i8 157)
394  ret i8 %r
395}
396
397; We have a constant range for the LHS, but only known bits for the RHS
398define i8 @test_scalar_uadd_udiv_known_bits(i8 %a, i8 %b) {
399; CHECK-LABEL: @test_scalar_uadd_udiv_known_bits(
400; CHECK-NEXT:    [[AA:%.*]] = udiv i8 -66, [[A:%.*]]
401; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 63
402; CHECK-NEXT:    [[R:%.*]] = add nuw i8 [[AA]], [[BB]]
403; CHECK-NEXT:    ret i8 [[R]]
404;
405  %aa = udiv i8 190, %a
406  %bb = and i8 %b, 63
407  %r = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %bb)
408  ret i8 %r
409}
410
411define i8 @test_scalar_sadd_srem_no_ov(i8 %a) {
412; CHECK-LABEL: @test_scalar_sadd_srem_no_ov(
413; CHECK-NEXT:    [[B:%.*]] = srem i8 [[A:%.*]], 100
414; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[B]], 28
415; CHECK-NEXT:    ret i8 [[R]]
416;
417  %b = srem i8 %a, 100
418  %r = call i8 @llvm.sadd.sat.i8(i8 %b, i8 28)
419  ret i8 %r
420}
421
422define i8 @test_scalar_sadd_srem_may_ov(i8 %a) {
423; CHECK-LABEL: @test_scalar_sadd_srem_may_ov(
424; CHECK-NEXT:    [[B:%.*]] = srem i8 [[A:%.*]], 100
425; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B]], i8 29)
426; CHECK-NEXT:    ret i8 [[R]]
427;
428  %b = srem i8 %a, 100
429  %r = call i8 @llvm.sadd.sat.i8(i8 %b, i8 29)
430  ret i8 %r
431}
432
433define i8 @test_scalar_sadd_srem_and_no_ov(i8 %a, i8 %b) {
434; CHECK-LABEL: @test_scalar_sadd_srem_and_no_ov(
435; CHECK-NEXT:    [[AA:%.*]] = srem i8 [[A:%.*]], 100
436; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 15
437; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[AA]], [[BB]]
438; CHECK-NEXT:    ret i8 [[R]]
439;
440  %aa = srem i8 %a, 100
441  %bb = and i8 %b, 15
442  %r = call i8 @llvm.sadd.sat.i8(i8 %aa, i8 %bb)
443  ret i8 %r
444}
445
446;
447; Saturating subtraction.
448;
449
450declare i8 @llvm.usub.sat.i8(i8, i8)
451declare i8 @llvm.ssub.sat.i8(i8, i8)
452declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
453declare <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8>, <2 x i8>)
454
455; Cannot canonicalize usub to uadd.
456define i8 @test_scalar_usub_canonical(i8 %a) {
457; CHECK-LABEL: @test_scalar_usub_canonical(
458; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
459; CHECK-NEXT:    ret i8 [[R]]
460;
461  %r = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
462  ret i8 %r
463}
464
465; Canonicalize ssub to sadd.
466define i8 @test_scalar_ssub_canonical(i8 %a) {
467; CHECK-LABEL: @test_scalar_ssub_canonical(
468; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
469; CHECK-NEXT:    ret i8 [[R]]
470;
471  %r = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
472  ret i8 %r
473}
474
475define <2 x i8> @test_vector_ssub_canonical(<2 x i8> %a) {
476; CHECK-LABEL: @test_vector_ssub_canonical(
477; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 -10))
478; CHECK-NEXT:    ret <2 x i8> [[R]]
479;
480  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
481  ret <2 x i8> %r
482}
483
484define <2 x i8> @test_vector_ssub_canonical_min_non_splat(<2 x i8> %a) {
485; CHECK-LABEL: @test_vector_ssub_canonical_min_non_splat(
486; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -10, i8 10>)
487; CHECK-NEXT:    ret <2 x i8> [[R]]
488;
489  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 -10>)
490  ret <2 x i8> %r
491}
492
493; Cannot canonicalize signed min.
494define i8 @test_scalar_ssub_canonical_min(i8 %a) {
495; CHECK-LABEL: @test_scalar_ssub_canonical_min(
496; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 -128)
497; CHECK-NEXT:    ret i8 [[R]]
498;
499  %r = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -128)
500  ret i8 %r
501}
502
503define <2 x i8> @test_vector_ssub_canonical_min(<2 x i8> %a) {
504; CHECK-LABEL: @test_vector_ssub_canonical_min(
505; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -128, i8 -10>)
506; CHECK-NEXT:    ret <2 x i8> [[R]]
507;
508  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 -128, i8 -10>)
509  ret <2 x i8> %r
510}
511
512; Can combine usubs with constant operands.
513define i8 @test_scalar_usub_combine(i8 %a) {
514; CHECK-LABEL: @test_scalar_usub_combine(
515; CHECK-NEXT:    [[X2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 30)
516; CHECK-NEXT:    ret i8 [[X2]]
517;
518  %x1 = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
519  %x2 = call i8 @llvm.usub.sat.i8(i8 %x1, i8 20)
520  ret i8 %x2
521}
522
523; Can simplify zero check followed by decrement
524define i8 @test_simplify_decrement(i8 %a) {
525; CHECK-LABEL: @test_simplify_decrement(
526; CHECK-NEXT:    [[I2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 1)
527; CHECK-NEXT:    ret i8 [[I2]]
528;
529  %i = icmp eq i8 %a, 0
530  %i1 = sub i8 %a, 1
531  %i2 = select i1 %i, i8 0, i8 %i1
532  ret i8 %i2
533}
534
535declare void @use.i1(i1)
536
537define i8 @test_simplify_decrement_ne(i8 %a) {
538; CHECK-LABEL: @test_simplify_decrement_ne(
539; CHECK-NEXT:    [[I:%.*]] = icmp ne i8 [[A:%.*]], 0
540; CHECK-NEXT:    call void @use.i1(i1 [[I]])
541; CHECK-NEXT:    [[I2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A]], i8 1)
542; CHECK-NEXT:    ret i8 [[I2]]
543;
544  %i = icmp ne i8 %a, 0
545  call void @use.i1(i1 %i)
546  %i1 = add i8 %a, -1
547  %i2 = select i1 %i, i8 %i1, i8 0
548  ret i8 %i2
549}
550
551define <2 x i8> @test_simplify_decrement_vec(<2 x i8> %a) {
552; CHECK-LABEL: @test_simplify_decrement_vec(
553; CHECK-NEXT:    [[I2:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 1))
554; CHECK-NEXT:    ret <2 x i8> [[I2]]
555;
556  %i = icmp eq <2 x i8> %a, <i8 0, i8 0>
557  %i1 = sub <2 x i8> %a, <i8 1, i8 1>
558  %i2 = select <2 x i1> %i, <2 x i8> <i8 0, i8 0>, <2 x i8> %i1
559  ret <2 x i8> %i2
560}
561
562define <2 x i8> @test_simplify_decrement_vec_poison(<2 x i8> %a) {
563; CHECK-LABEL: @test_simplify_decrement_vec_poison(
564; CHECK-NEXT:    [[I2:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 1))
565; CHECK-NEXT:    ret <2 x i8> [[I2]]
566;
567  %i = icmp eq <2 x i8> %a, <i8 0, i8 0>
568  %i1 = sub <2 x i8> %a, <i8 1, i8 1>
569  %i2 = select <2 x i1> %i, <2 x i8> <i8 0, i8 poison>, <2 x i8> %i1
570  ret <2 x i8> %i2
571}
572
573define i8 @test_simplify_decrement_invalid_ne(i8 %a) {
574; CHECK-LABEL: @test_simplify_decrement_invalid_ne(
575; CHECK-NEXT:    [[I_NOT:%.*]] = icmp eq i8 [[A:%.*]], 0
576; CHECK-NEXT:    [[I2:%.*]] = sext i1 [[I_NOT]] to i8
577; CHECK-NEXT:    ret i8 [[I2]]
578;
579  %i = icmp ne i8 %a, 0
580  %i1 = sub i8 %a, 1
581  %i2 = select i1 %i, i8 0, i8 %i1
582  ret i8 %i2
583}
584
585define i8 @test_invalid_simplify_sub2(i8 %a) {
586; CHECK-LABEL: @test_invalid_simplify_sub2(
587; CHECK-NEXT:    [[I:%.*]] = icmp eq i8 [[A:%.*]], 0
588; CHECK-NEXT:    [[I1:%.*]] = add i8 [[A]], -2
589; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I]], i8 0, i8 [[I1]]
590; CHECK-NEXT:    ret i8 [[I2]]
591;
592  %i = icmp eq i8 %a, 0
593  %i1 = sub i8 %a, 2
594  %i2 = select i1 %i, i8 0, i8 %i1
595  ret i8 %i2
596}
597
598define i8 @test_invalid_simplify_eq2(i8 %a) {
599; CHECK-LABEL: @test_invalid_simplify_eq2(
600; CHECK-NEXT:    [[I:%.*]] = icmp eq i8 [[A:%.*]], 2
601; CHECK-NEXT:    [[I1:%.*]] = add i8 [[A]], -1
602; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I]], i8 0, i8 [[I1]]
603; CHECK-NEXT:    ret i8 [[I2]]
604;
605  %i = icmp eq i8 %a, 2
606  %i1 = sub i8 %a, 1
607  %i2 = select i1 %i, i8 0, i8 %i1
608  ret i8 %i2
609}
610
611define i8 @test_invalid_simplify_select_1(i8 %a) {
612; CHECK-LABEL: @test_invalid_simplify_select_1(
613; CHECK-NEXT:    [[I:%.*]] = icmp eq i8 [[A:%.*]], 0
614; CHECK-NEXT:    [[I1:%.*]] = add i8 [[A]], -1
615; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I]], i8 1, i8 [[I1]]
616; CHECK-NEXT:    ret i8 [[I2]]
617;
618  %i = icmp eq i8 %a, 0
619  %i1 = sub i8 %a, 1
620  %i2 = select i1 %i, i8 1, i8 %i1
621  ret i8 %i2
622}
623
624define i8 @test_invalid_simplify_other(i8 %a, i8 %b) {
625; CHECK-LABEL: @test_invalid_simplify_other(
626; CHECK-NEXT:    [[I:%.*]] = icmp eq i8 [[A:%.*]], 0
627; CHECK-NEXT:    [[I1:%.*]] = add i8 [[B:%.*]], -1
628; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I]], i8 0, i8 [[I1]]
629; CHECK-NEXT:    ret i8 [[I2]]
630;
631  %i = icmp eq i8 %a, 0
632  %i1 = sub i8 %b, 1
633  %i2 = select i1 %i, i8 0, i8 %i1
634  ret i8 %i2
635}
636
637define <2 x i8> @test_vector_usub_combine(<2 x i8> %a) {
638; CHECK-LABEL: @test_vector_usub_combine(
639; CHECK-NEXT:    [[X2:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 30))
640; CHECK-NEXT:    ret <2 x i8> [[X2]]
641;
642  %x1 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
643  %x2 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x1, <2 x i8> <i8 20, i8 20>)
644  ret <2 x i8> %x2
645}
646
647; This could simplify, but currently doesn't.
648define <2 x i8> @test_vector_usub_combine_non_splat(<2 x i8> %a) {
649; CHECK-LABEL: @test_vector_usub_combine_non_splat(
650; CHECK-NEXT:    [[X1:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 20>)
651; CHECK-NEXT:    [[X2:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X1]], <2 x i8> <i8 30, i8 40>)
652; CHECK-NEXT:    ret <2 x i8> [[X2]]
653;
654  %x1 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 20>)
655  %x2 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x1, <2 x i8> <i8 30, i8 40>)
656  ret <2 x i8> %x2
657}
658
659; Can combine usubs even if they overflow.
660define i8 @test_scalar_usub_overflow(i8 %a) {
661; CHECK-LABEL: @test_scalar_usub_overflow(
662; CHECK-NEXT:    ret i8 0
663;
664  %y1 = call i8 @llvm.usub.sat.i8(i8 %a, i8 100)
665  %y2 = call i8 @llvm.usub.sat.i8(i8 %y1, i8 200)
666  ret i8 %y2
667}
668
669define <2 x i8> @test_vector_usub_overflow(<2 x i8> %a) {
670; CHECK-LABEL: @test_vector_usub_overflow(
671; CHECK-NEXT:    ret <2 x i8> zeroinitializer
672;
673  %y1 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 100, i8 100>)
674  %y2 = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %y1, <2 x i8> <i8 200, i8 200>)
675  ret <2 x i8> %y2
676}
677
678; Can combine ssubs if sign matches.
679define i8 @test_scalar_ssub_both_positive(i8 %a) {
680; CHECK-LABEL: @test_scalar_ssub_both_positive(
681; CHECK-NEXT:    [[Z2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -30)
682; CHECK-NEXT:    ret i8 [[Z2]]
683;
684  %z1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
685  %z2 = call i8 @llvm.ssub.sat.i8(i8 %z1, i8 20)
686  ret i8 %z2
687}
688
689define <2 x i8> @test_vector_ssub_both_positive(<2 x i8> %a) {
690; CHECK-LABEL: @test_vector_ssub_both_positive(
691; CHECK-NEXT:    [[Z2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 -30))
692; CHECK-NEXT:    ret <2 x i8> [[Z2]]
693;
694  %z1 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
695  %z2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %z1, <2 x i8> <i8 20, i8 20>)
696  ret <2 x i8> %z2
697}
698
699define i8 @test_scalar_ssub_both_negative(i8 %a) {
700; CHECK-LABEL: @test_scalar_ssub_both_negative(
701; CHECK-NEXT:    [[U2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 30)
702; CHECK-NEXT:    ret i8 [[U2]]
703;
704  %u1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -10)
705  %u2 = call i8 @llvm.ssub.sat.i8(i8 %u1, i8 -20)
706  ret i8 %u2
707}
708
709define <2 x i8> @test_vector_ssub_both_negative(<2 x i8> %a) {
710; CHECK-LABEL: @test_vector_ssub_both_negative(
711; CHECK-NEXT:    [[U2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 30))
712; CHECK-NEXT:    ret <2 x i8> [[U2]]
713;
714  %u1 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 -10, i8 -10>)
715  %u2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %u1, <2 x i8> <i8 -20, i8 -20>)
716  ret <2 x i8> %u2
717}
718
719; Can't combine ssubs if constants have different sign.
720define i8 @test_scalar_ssub_different_sign(i8 %a) {
721; CHECK-LABEL: @test_scalar_ssub_different_sign(
722; CHECK-NEXT:    [[V1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
723; CHECK-NEXT:    [[V2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[V1]], i8 20)
724; CHECK-NEXT:    ret i8 [[V2]]
725;
726  %v1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
727  %v2 = call i8 @llvm.ssub.sat.i8(i8 %v1, i8 -20)
728  ret i8 %v2
729}
730
731; Can combine sadd and ssub with appropriate signs.
732define i8 @test_scalar_sadd_ssub(i8 %a) {
733; CHECK-LABEL: @test_scalar_sadd_ssub(
734; CHECK-NEXT:    [[V2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 30)
735; CHECK-NEXT:    ret i8 [[V2]]
736;
737  %v1 = call i8 @llvm.sadd.sat.i8(i8 10, i8 %a)
738  %v2 = call i8 @llvm.ssub.sat.i8(i8 %v1, i8 -20)
739  ret i8 %v2
740}
741
742define <2 x i8> @test_vector_sadd_ssub(<2 x i8> %a) {
743; CHECK-LABEL: @test_vector_sadd_ssub(
744; CHECK-NEXT:    [[V2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 -30))
745; CHECK-NEXT:    ret <2 x i8> [[V2]]
746;
747  %v1 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 -10, i8 -10>, <2 x i8> %a)
748  %v2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %v1, <2 x i8> <i8 20, i8 20>)
749  ret <2 x i8> %v2
750}
751
752; Can't combine ssubs if they overflow.
753define i8 @test_scalar_ssub_overflow(i8 %a) {
754; CHECK-LABEL: @test_scalar_ssub_overflow(
755; CHECK-NEXT:    [[W1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -100)
756; CHECK-NEXT:    [[W2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[W1]], i8 -100)
757; CHECK-NEXT:    ret i8 [[W2]]
758;
759  %w1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 100)
760  %w2 = call i8 @llvm.ssub.sat.i8(i8 %w1, i8 100)
761  ret i8 %w2
762}
763
764; nneg usub neg always overflows.
765define i8 @test_scalar_usub_nneg_neg(i8 %a) {
766; CHECK-LABEL: @test_scalar_usub_nneg_neg(
767; CHECK-NEXT:    ret i8 0
768;
769  %a_nneg = and i8 %a, 127
770  %r = call i8 @llvm.usub.sat.i8(i8 %a_nneg, i8 -10)
771  ret i8 %r
772}
773
774define <2 x i8> @test_vector_usub_nneg_neg(<2 x i8> %a) {
775; CHECK-LABEL: @test_vector_usub_nneg_neg(
776; CHECK-NEXT:    ret <2 x i8> zeroinitializer
777;
778  %a_nneg = and <2 x i8> %a, <i8 127, i8 127>
779  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a_nneg, <2 x i8> <i8 -10, i8 -20>)
780  ret <2 x i8> %r
781}
782
783; neg usub nneg never overflows.
784define i8 @test_scalar_usub_neg_nneg(i8 %a) {
785; CHECK-LABEL: @test_scalar_usub_neg_nneg(
786; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
787; CHECK-NEXT:    [[R:%.*]] = add i8 [[A_NEG]], -10
788; CHECK-NEXT:    ret i8 [[R]]
789;
790  %a_neg = or i8 %a, -128
791  %r = call i8 @llvm.usub.sat.i8(i8 %a_neg, i8 10)
792  ret i8 %r
793}
794
795define <2 x i8> @test_vector_usub_neg_nneg(<2 x i8> %a) {
796; CHECK-LABEL: @test_vector_usub_neg_nneg(
797; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
798; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[A_NEG]], <i8 -10, i8 -20>
799; CHECK-NEXT:    ret <2 x i8> [[R]]
800;
801  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
802  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 10, i8 20>)
803  ret <2 x i8> %r
804}
805
806; nneg usub nneg never may overflow.
807define i8 @test_scalar_usub_nneg_nneg(i8 %a) {
808; CHECK-LABEL: @test_scalar_usub_nneg_nneg(
809; CHECK-NEXT:    [[A_NNEG:%.*]] = and i8 [[A:%.*]], 127
810; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A_NNEG]], i8 10)
811; CHECK-NEXT:    ret i8 [[R]]
812;
813  %a_nneg = and i8 %a, 127
814  %r = call i8 @llvm.usub.sat.i8(i8 %a_nneg, i8 10)
815  ret i8 %r
816}
817
818define <2 x i8> @test_vector_usub_nneg_nneg(<2 x i8> %a) {
819; CHECK-LABEL: @test_vector_usub_nneg_nneg(
820; CHECK-NEXT:    [[A_NNEG:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 127)
821; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A_NNEG]], <2 x i8> <i8 10, i8 20>)
822; CHECK-NEXT:    ret <2 x i8> [[R]]
823;
824  %a_nneg = and <2 x i8> %a, <i8 127, i8 127>
825  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a_nneg, <2 x i8> <i8 10, i8 20>)
826  ret <2 x i8> %r
827}
828
829define i8 @test_scalar_usub_never_overflows(i8 %a) {
830; CHECK-LABEL: @test_scalar_usub_never_overflows(
831; CHECK-NEXT:    [[A_MASKED:%.*]] = or i8 [[A:%.*]], 64
832; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A_MASKED]], -10
833; CHECK-NEXT:    ret i8 [[R]]
834;
835  %a_masked = or i8 %a, 64
836  %r = call i8 @llvm.usub.sat.i8(i8 %a_masked, i8 10)
837  ret i8 %r
838}
839
840define <2 x i8> @test_vector_usub_never_overflows(<2 x i8> %a) {
841; CHECK-LABEL: @test_vector_usub_never_overflows(
842; CHECK-NEXT:    [[A_MASKED:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 64)
843; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[A_MASKED]], splat (i8 -10)
844; CHECK-NEXT:    ret <2 x i8> [[R]]
845;
846  %a_masked = or <2 x i8> %a, <i8 64, i8 64>
847  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a_masked, <2 x i8> <i8 10, i8 10>)
848  ret <2 x i8> %r
849}
850
851define i8 @test_scalar_usub_always_overflows(i8 %a) {
852; CHECK-LABEL: @test_scalar_usub_always_overflows(
853; CHECK-NEXT:    ret i8 0
854;
855  %a_masked = and i8 %a, 64
856  %r = call i8 @llvm.usub.sat.i8(i8 %a_masked, i8 100)
857  ret i8 %r
858}
859
860define <2 x i8> @test_vector_usub_always_overflows(<2 x i8> %a) {
861; CHECK-LABEL: @test_vector_usub_always_overflows(
862; CHECK-NEXT:    ret <2 x i8> zeroinitializer
863;
864  %a_masked = and <2 x i8> %a, <i8 64, i8 64>
865  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a_masked, <2 x i8> <i8 100, i8 100>)
866  ret <2 x i8> %r
867}
868
869; neg ssub neg never overflows.
870define i8 @test_scalar_ssub_neg_neg(i8 %a) {
871; CHECK-LABEL: @test_scalar_ssub_neg_neg(
872; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
873; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A_NEG]], 10
874; CHECK-NEXT:    ret i8 [[R]]
875;
876  %a_neg = or i8 %a, -128
877  %r = call i8 @llvm.ssub.sat.i8(i8 %a_neg, i8 -10)
878  ret i8 %r
879}
880
881define <2 x i8> @test_vector_ssub_neg_neg(<2 x i8> %a) {
882; CHECK-LABEL: @test_vector_ssub_neg_neg(
883; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
884; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[A_NEG]], <i8 10, i8 20>
885; CHECK-NEXT:    ret <2 x i8> [[R]]
886;
887  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
888  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 -10, i8 -20>)
889  ret <2 x i8> %r
890}
891
892; nneg ssub nneg never overflows.
893define i8 @test_scalar_ssub_nneg_nneg(i8 %a) {
894; CHECK-LABEL: @test_scalar_ssub_nneg_nneg(
895; CHECK-NEXT:    [[A_NNEG:%.*]] = and i8 [[A:%.*]], 127
896; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A_NNEG]], -10
897; CHECK-NEXT:    ret i8 [[R]]
898;
899  %a_nneg = and i8 %a, 127
900  %r = call i8 @llvm.ssub.sat.i8(i8 %a_nneg, i8 10)
901  ret i8 %r
902}
903
904define <2 x i8> @test_vector_ssub_nneg_nneg(<2 x i8> %a) {
905; CHECK-LABEL: @test_vector_ssub_nneg_nneg(
906; CHECK-NEXT:    [[A_NNEG:%.*]] = and <2 x i8> [[A:%.*]], splat (i8 127)
907; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[A_NNEG]], <i8 -10, i8 -20>
908; CHECK-NEXT:    ret <2 x i8> [[R]]
909;
910  %a_nneg = and <2 x i8> %a, <i8 127, i8 127>
911  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a_nneg, <2 x i8> <i8 10, i8 20>)
912  ret <2 x i8> %r
913}
914
915; neg ssub nneg may overflow.
916define i8 @test_scalar_ssub_neg_nneg(i8 %a) {
917; CHECK-LABEL: @test_scalar_ssub_neg_nneg(
918; CHECK-NEXT:    [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
919; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A_NEG]], i8 -10)
920; CHECK-NEXT:    ret i8 [[R]]
921;
922  %a_neg = or i8 %a, -128
923  %r = call i8 @llvm.ssub.sat.i8(i8 %a_neg, i8 10)
924  ret i8 %r
925}
926
927define <2 x i8> @test_vector_ssub_neg_nneg(<2 x i8> %a) {
928; CHECK-LABEL: @test_vector_ssub_neg_nneg(
929; CHECK-NEXT:    [[A_NEG:%.*]] = or <2 x i8> [[A:%.*]], splat (i8 -128)
930; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A_NEG]], <2 x i8> <i8 -10, i8 -20>)
931; CHECK-NEXT:    ret <2 x i8> [[R]]
932;
933  %a_neg = or <2 x i8> %a, <i8 -128, i8 -128>
934  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a_neg, <2 x i8> <i8 10, i8 20>)
935  ret <2 x i8> %r
936}
937
938define i8 @test_scalar_ssub_always_overflows_low(i8 %a) {
939; CHECK-LABEL: @test_scalar_ssub_always_overflows_low(
940; CHECK-NEXT:    ret i8 -128
941;
942  %cmp = icmp sgt i8 %a, 120
943  %max = select i1 %cmp, i8 %a, i8 120
944  %r = call i8 @llvm.ssub.sat.i8(i8 -10, i8 %max)
945  ret i8 %r
946}
947
948define i8 @test_scalar_ssub_always_overflows_high(i8 %a) {
949; CHECK-LABEL: @test_scalar_ssub_always_overflows_high(
950; CHECK-NEXT:    ret i8 127
951;
952  %cmp = icmp slt i8 %a, -120
953  %min = select i1 %cmp, i8 %a, i8 -120
954  %r = call i8 @llvm.ssub.sat.i8(i8 10, i8 %min)
955  ret i8 %r
956}
957
958define i8 @test_scalar_usub_add_nuw_no_ov(i8 %a) {
959; CHECK-LABEL: @test_scalar_usub_add_nuw_no_ov(
960; CHECK-NEXT:    [[R:%.*]] = add i8 [[A:%.*]], 1
961; CHECK-NEXT:    ret i8 [[R]]
962;
963  %b = add nuw i8 %a, 10
964  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 9)
965  ret i8 %r
966}
967
968define i8 @test_scalar_usub_add_nuw_nsw_no_ov(i8 %a) {
969; CHECK-LABEL: @test_scalar_usub_add_nuw_nsw_no_ov(
970; CHECK-NEXT:    [[R:%.*]] = add i8 [[A:%.*]], 1
971; CHECK-NEXT:    ret i8 [[R]]
972;
973  %b = add nuw nsw i8 %a, 10
974  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 9)
975  ret i8 %r
976}
977
978define i8 @test_scalar_usub_add_nuw_eq(i8 %a) {
979; CHECK-LABEL: @test_scalar_usub_add_nuw_eq(
980; CHECK-NEXT:    ret i8 [[A:%.*]]
981;
982  %b = add nuw i8 %a, 10
983  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 10)
984  ret i8 %r
985}
986
987define i8 @test_scalar_usub_add_nuw_may_ov(i8 %a) {
988; CHECK-LABEL: @test_scalar_usub_add_nuw_may_ov(
989; CHECK-NEXT:    [[B:%.*]] = add nuw i8 [[A:%.*]], 10
990; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 11)
991; CHECK-NEXT:    ret i8 [[R]]
992;
993  %b = add nuw i8 %a, 10
994  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 11)
995  ret i8 %r
996}
997
998define i8 @test_scalar_usub_urem_must_ov(i8 %a) {
999; CHECK-LABEL: @test_scalar_usub_urem_must_ov(
1000; CHECK-NEXT:    ret i8 0
1001;
1002  %b = urem i8 %a, 10
1003  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 10)
1004  ret i8 %r
1005}
1006
1007; Like the previous case, the result is always zero here. However, as there's
1008; no actual overflow, we won't know about it.
1009define i8 @test_scalar_usub_urem_must_zero(i8 %a) {
1010; CHECK-LABEL: @test_scalar_usub_urem_must_zero(
1011; CHECK-NEXT:    [[B:%.*]] = urem i8 [[A:%.*]], 10
1012; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 9)
1013; CHECK-NEXT:    ret i8 [[R]]
1014;
1015  %b = urem i8 %a, 10
1016  %r = call i8 @llvm.usub.sat.i8(i8 %b, i8 9)
1017  ret i8 %r
1018}
1019
1020; We have a constant range for the LHS, but only known bits for the RHS
1021define i8 @test_scalar_usub_add_nuw_known_bits(i8 %a, i8 %b) {
1022; CHECK-LABEL: @test_scalar_usub_add_nuw_known_bits(
1023; CHECK-NEXT:    [[AA:%.*]] = add nuw i8 [[A:%.*]], 10
1024; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 7
1025; CHECK-NEXT:    [[R:%.*]] = sub nuw i8 [[AA]], [[BB]]
1026; CHECK-NEXT:    ret i8 [[R]]
1027;
1028  %aa = add nuw i8 %a, 10
1029  %bb = and i8 %b, 7
1030  %r = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %bb)
1031  ret i8 %r
1032}
1033
1034define i8 @test_scalar_usub_add_nuw_inferred(i8 %a) {
1035; CHECK-LABEL: @test_scalar_usub_add_nuw_inferred(
1036; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
1037; CHECK-NEXT:    [[R:%.*]] = add nuw i8 [[B]], 9
1038; CHECK-NEXT:    ret i8 [[R]]
1039;
1040  %b = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
1041  %r = add i8 %b, 9
1042  ret i8 %r
1043}
1044
1045define <2 x i8> @test_vector_usub_add_nuw_no_ov(<2 x i8> %a) {
1046; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov(
1047; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[A:%.*]], splat (i8 1)
1048; CHECK-NEXT:    ret <2 x i8> [[R]]
1049;
1050  %b = add nuw <2 x i8> %a, <i8 10, i8 10>
1051  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %b, <2 x i8> <i8 9, i8 9>)
1052  ret <2 x i8> %r
1053}
1054
1055define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1(<2 x i8> %a) {
1056; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat1(
1057; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[A:%.*]], <i8 0, i8 1>
1058; CHECK-NEXT:    ret <2 x i8> [[R]]
1059;
1060  %b = add nuw <2 x i8> %a, <i8 10, i8 10>
1061  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %b, <2 x i8> <i8 10, i8 9>)
1062  ret <2 x i8> %r
1063}
1064
1065define <3 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat1_poison(<3 x i8> %a) {
1066; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat1_poison(
1067; CHECK-NEXT:    [[R:%.*]] = add <3 x i8> [[A:%.*]], <i8 0, i8 1, i8 poison>
1068; CHECK-NEXT:    ret <3 x i8> [[R]]
1069;
1070  %b = add nuw <3 x i8> %a, <i8 10, i8 10, i8 10>
1071  %r = call <3 x i8> @llvm.usub.sat.v3i8(<3 x i8> %b, <3 x i8> <i8 10, i8 9, i8 poison>)
1072  ret <3 x i8> %r
1073}
1074
1075; Can be optimized if the add nuw RHS constant range handles non-splat vectors.
1076define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat2(<2 x i8> %a) {
1077; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat2(
1078; CHECK-NEXT:    [[B:%.*]] = add nuw <2 x i8> [[A:%.*]], <i8 10, i8 9>
1079; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> splat (i8 9))
1080; CHECK-NEXT:    ret <2 x i8> [[R]]
1081;
1082  %b = add nuw <2 x i8> %a, <i8 10, i8 9>
1083  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %b, <2 x i8> <i8 9, i8 9>)
1084  ret <2 x i8> %r
1085}
1086
1087; Can be optimized if constant range is tracked per-element.
1088define <2 x i8> @test_vector_usub_add_nuw_no_ov_nonsplat3(<2 x i8> %a) {
1089; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov_nonsplat3(
1090; CHECK-NEXT:    [[B:%.*]] = add nuw <2 x i8> [[A:%.*]], <i8 10, i8 9>
1091; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> <i8 10, i8 9>)
1092; CHECK-NEXT:    ret <2 x i8> [[R]]
1093;
1094  %b = add nuw <2 x i8> %a, <i8 10, i8 9>
1095  %r = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %b, <2 x i8> <i8 10, i8 9>)
1096  ret <2 x i8> %r
1097}
1098
1099define i8 @test_scalar_ssub_add_nsw_no_ov(i8 %a, i8 %b) {
1100; CHECK-LABEL: @test_scalar_ssub_add_nsw_no_ov(
1101; CHECK-NEXT:    [[AA:%.*]] = add nsw i8 [[A:%.*]], 7
1102; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 7
1103; CHECK-NEXT:    [[R:%.*]] = sub nsw i8 [[AA]], [[BB]]
1104; CHECK-NEXT:    ret i8 [[R]]
1105;
1106  %aa = add nsw i8 %a, 7
1107  %bb = and i8 %b, 7
1108  %r = call i8 @llvm.ssub.sat.i8(i8 %aa, i8 %bb)
1109  ret i8 %r
1110}
1111
1112define i8 @test_scalar_ssub_add_nsw_may_ov(i8 %a, i8 %b) {
1113; CHECK-LABEL: @test_scalar_ssub_add_nsw_may_ov(
1114; CHECK-NEXT:    [[AA:%.*]] = add nsw i8 [[A:%.*]], 6
1115; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 7
1116; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[AA]], i8 [[BB]])
1117; CHECK-NEXT:    ret i8 [[R]]
1118;
1119  %aa = add nsw i8 %a, 6
1120  %bb = and i8 %b, 7
1121  %r = call i8 @llvm.ssub.sat.i8(i8 %aa, i8 %bb)
1122  ret i8 %r
1123}
1124
1125define <2 x i8> @test_vector_ssub_add_nsw_no_ov_splat(<2 x i8> %a, <2 x i8> %b) {
1126; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_splat(
1127; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], splat (i8 7)
1128; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 7)
1129; CHECK-NEXT:    [[R:%.*]] = sub nsw <2 x i8> [[AA]], [[BB]]
1130; CHECK-NEXT:    ret <2 x i8> [[R]]
1131;
1132  %aa = add nsw <2 x i8> %a, <i8 7, i8 7>
1133  %bb = and <2 x i8> %b, <i8 7, i8 7>
1134  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %aa, <2 x i8> %bb)
1135  ret <2 x i8> %r
1136}
1137
1138define <2 x i8> @test_vector_ssub_add_nsw_no_ov_nonsplat1(<2 x i8> %a, <2 x i8> %b) {
1139; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_nonsplat1(
1140; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], splat (i8 7)
1141; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], <i8 7, i8 6>
1142; CHECK-NEXT:    [[R:%.*]] = sub nsw <2 x i8> [[AA]], [[BB]]
1143; CHECK-NEXT:    ret <2 x i8> [[R]]
1144;
1145  %aa = add nsw <2 x i8> %a, <i8 7, i8 7>
1146  %bb = and <2 x i8> %b, <i8 7, i8 6>
1147  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %aa, <2 x i8> %bb)
1148  ret <2 x i8> %r
1149}
1150
1151define <2 x i8> @test_vector_ssub_add_nsw_no_ov_nonsplat2(<2 x i8> %a, <2 x i8> %b) {
1152; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_nonsplat2(
1153; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], <i8 7, i8 8>
1154; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 7)
1155; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[AA]], <2 x i8> [[BB]])
1156; CHECK-NEXT:    ret <2 x i8> [[R]]
1157;
1158  %aa = add nsw <2 x i8> %a, <i8 7, i8 8>
1159  %bb = and <2 x i8> %b, <i8 7, i8 7>
1160  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %aa, <2 x i8> %bb)
1161  ret <2 x i8> %r
1162}
1163
1164define <2 x i8> @test_vector_ssub_add_nsw_no_ov_nonsplat3(<2 x i8> %a, <2 x i8> %b) {
1165; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_nonsplat3(
1166; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], <i8 7, i8 6>
1167; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], <i8 7, i8 6>
1168; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[AA]], <2 x i8> [[BB]])
1169; CHECK-NEXT:    ret <2 x i8> [[R]]
1170;
1171  %aa = add nsw <2 x i8> %a, <i8 7, i8 6>
1172  %bb = and <2 x i8> %b, <i8 7, i8 6>
1173  %r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %aa, <2 x i8> %bb)
1174  ret <2 x i8> %r
1175}
1176
1177define i8 @test_scalar_usub_add(i8 %a, i8 %b) {
1178; CHECK-LABEL: @test_scalar_usub_add(
1179; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1180; CHECK-NEXT:    ret i8 [[RES]]
1181;
1182  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1183  %res = add i8 %sat, %b
1184  ret i8 %res
1185}
1186
1187define i8 @test_scalar_usub_add_extra_use(i8 %a, i8 %b, ptr %p) {
1188; CHECK-LABEL: @test_scalar_usub_add_extra_use(
1189; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1190; CHECK-NEXT:    store i8 [[SAT]], ptr [[P:%.*]], align 1
1191; CHECK-NEXT:    [[RES:%.*]] = add i8 [[SAT]], [[B]]
1192; CHECK-NEXT:    ret i8 [[RES]]
1193;
1194  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1195  store i8 %sat, ptr %p
1196  %res = add i8 %sat, %b
1197  ret i8 %res
1198}
1199
1200define i8 @test_scalar_usub_add_commuted(i8 %a, i8 %b) {
1201; CHECK-LABEL: @test_scalar_usub_add_commuted(
1202; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1203; CHECK-NEXT:    ret i8 [[RES]]
1204;
1205  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1206  %res = add i8 %b, %sat
1207  ret i8 %res
1208}
1209
1210define i8 @test_scalar_usub_add_commuted_wrong(i8 %a, i8 %b) {
1211; CHECK-LABEL: @test_scalar_usub_add_commuted_wrong(
1212; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
1213; CHECK-NEXT:    [[RES:%.*]] = add i8 [[SAT]], [[B]]
1214; CHECK-NEXT:    ret i8 [[RES]]
1215;
1216  %sat = call i8 @llvm.usub.sat.i8(i8 %b, i8 %a)
1217  %res = add i8 %sat, %b
1218  ret i8 %res
1219}
1220
1221define i8 @test_scalar_usub_add_const(i8 %a) {
1222; CHECK-LABEL: @test_scalar_usub_add_const(
1223; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 42)
1224; CHECK-NEXT:    ret i8 [[RES]]
1225;
1226  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 42)
1227  %res = add i8 %sat, 42
1228  ret i8 %res
1229}
1230
1231define i8 @test_scalar_usub_sub(i8 %a, i8 %b) {
1232; CHECK-LABEL: @test_scalar_usub_sub(
1233; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1234; CHECK-NEXT:    ret i8 [[RES]]
1235;
1236  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1237  %res = sub i8 %a, %sat
1238  ret i8 %res
1239}
1240
1241define i8 @test_scalar_usub_sub_extra_use(i8 %a, i8 %b, ptr %p) {
1242; CHECK-LABEL: @test_scalar_usub_sub_extra_use(
1243; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1244; CHECK-NEXT:    store i8 [[SAT]], ptr [[P:%.*]], align 1
1245; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[A]], [[SAT]]
1246; CHECK-NEXT:    ret i8 [[RES]]
1247;
1248  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1249  store i8 %sat, ptr %p
1250  %res = sub i8 %a, %sat
1251  ret i8 %res
1252}
1253
1254define <2 x i8> @test_vector_usub_sub(<2 x i8> %a, <2 x i8> %b) {
1255; CHECK-LABEL: @test_vector_usub_sub(
1256; CHECK-NEXT:    [[RES:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]])
1257; CHECK-NEXT:    ret <2 x i8> [[RES]]
1258;
1259  %sat = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %a, <2 x i8> %b)
1260  %res = sub <2 x i8> %a, %sat
1261  ret <2 x i8> %res
1262}
1263
1264define i8 @test_scalar_usub_sub_wrong(i8 %a, i8 %b) {
1265; CHECK-LABEL: @test_scalar_usub_sub_wrong(
1266; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1267; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[SAT]]
1268; CHECK-NEXT:    ret i8 [[RES]]
1269;
1270  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1271  %res = sub i8 %b, %sat
1272  ret i8 %res
1273}
1274
1275define i8 @test_scalar_usub_sub_wrong2(i8 %a, i8 %b) {
1276; CHECK-LABEL: @test_scalar_usub_sub_wrong2(
1277; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1278; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[SAT]], [[B]]
1279; CHECK-NEXT:    ret i8 [[RES]]
1280;
1281  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1282  %res = sub i8 %sat, %b
1283  ret i8 %res
1284}
1285
1286define i8 @test_scalar_uadd_sub(i8 %a, i8 %b) {
1287; CHECK-LABEL: @test_scalar_uadd_sub(
1288; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1289; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[SAT]], [[B]]
1290; CHECK-NEXT:    ret i8 [[RES]]
1291;
1292  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 %b)
1293  %res = sub i8 %sat, %b
1294  ret i8 %res
1295}
1296
1297define i8 @test_scalar_uadd_sub_extra_use(i8 %a, i8 %b, ptr %p) {
1298; CHECK-LABEL: @test_scalar_uadd_sub_extra_use(
1299; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1300; CHECK-NEXT:    store i8 [[SAT]], ptr [[P:%.*]], align 1
1301; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[SAT]], [[B]]
1302; CHECK-NEXT:    ret i8 [[RES]]
1303;
1304  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 %b)
1305  store i8 %sat, ptr %p
1306  %res = sub i8 %sat, %b
1307  ret i8 %res
1308}
1309
1310define i8 @test_scalar_uadd_sub_commuted(i8 %a, i8 %b) {
1311; CHECK-LABEL: @test_scalar_uadd_sub_commuted(
1312; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
1313; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[SAT]], [[B]]
1314; CHECK-NEXT:    ret i8 [[RES]]
1315;
1316  %sat = call i8 @llvm.uadd.sat.i8(i8 %b, i8 %a)
1317  %res = sub i8 %sat, %b
1318  ret i8 %res
1319}
1320
1321define i8 @test_scalar_uadd_sub_commuted_wrong(i8 %a, i8 %b) {
1322; CHECK-LABEL: @test_scalar_uadd_sub_commuted_wrong(
1323; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
1324; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[SAT]]
1325; CHECK-NEXT:    ret i8 [[RES]]
1326;
1327  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 %b)
1328  %res = sub i8 %b, %sat
1329  ret i8 %res
1330}
1331
1332define i8 @test_scalar_uadd_sub_const(i8 %a) {
1333; CHECK-LABEL: @test_scalar_uadd_sub_const(
1334; CHECK-NEXT:    [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 42)
1335; CHECK-NEXT:    [[RES:%.*]] = add i8 [[SAT]], -42
1336; CHECK-NEXT:    ret i8 [[RES]]
1337;
1338  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 42)
1339  %res = sub i8 %sat, 42
1340  ret i8 %res
1341}
1342
1343define i1 @scalar_uadd_eq_zero(i8 %a, i8 %b) {
1344; CHECK-LABEL: @scalar_uadd_eq_zero(
1345; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
1346; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
1347; CHECK-NEXT:    ret i1 [[CMP]]
1348;
1349  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 %b)
1350  %cmp = icmp eq i8 %sat, 0
1351  ret i1 %cmp
1352}
1353
1354define i1 @scalar_uadd_ne_zero(i8 %a, i8 %b) {
1355; CHECK-LABEL: @scalar_uadd_ne_zero(
1356; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
1357; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
1358; CHECK-NEXT:    ret i1 [[CMP]]
1359;
1360  %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 %b)
1361  %cmp = icmp ne i8 %sat, 0
1362  ret i1 %cmp
1363}
1364
1365define i1 @scalar_usub_eq_zero(i8 %a, i8 %b) {
1366; CHECK-LABEL: @scalar_usub_eq_zero(
1367; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[A:%.*]], [[B:%.*]]
1368; CHECK-NEXT:    ret i1 [[CMP]]
1369;
1370  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1371  %cmp = icmp eq i8 %sat, 0
1372  ret i1 %cmp
1373}
1374
1375define i1 @scalar_usub_ne_zero(i8 %a, i8 %b) {
1376; CHECK-LABEL: @scalar_usub_ne_zero(
1377; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
1378; CHECK-NEXT:    ret i1 [[CMP]]
1379;
1380  %sat = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
1381  %cmp = icmp ne i8 %sat, 0
1382  ret i1 %cmp
1383}
1384
1385; Raw IR tests
1386
1387define i32 @uadd_sat(i32 %x, i32 %y) {
1388; CHECK-LABEL: @uadd_sat(
1389; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
1390; CHECK-NEXT:    ret i32 [[R]]
1391;
1392  %notx = xor i32 %x, -1
1393  %a = add i32 %y, %x
1394  %c = icmp ult i32 %notx, %y
1395  %r = select i1 %c, i32 -1, i32 %a
1396  ret i32 %r
1397}
1398
1399define i32 @uadd_sat_flipped(i32 %x) {
1400; CHECK-LABEL: @uadd_sat_flipped(
1401; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 9)
1402; CHECK-NEXT:    ret i32 [[COND]]
1403;
1404  %cmp = icmp ugt i32 %x, -11
1405  %add = add i32 %x, 9
1406  %cond = select i1 %cmp, i32 -1, i32 %add
1407  ret i32 %cond
1408}
1409
1410define i32 @uadd_sat_flipped2(i32 %x) {
1411; CHECK-LABEL: @uadd_sat_flipped2(
1412; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 9)
1413; CHECK-NEXT:    ret i32 [[COND]]
1414;
1415  %cmp = icmp ugt i32 %x, -10
1416  %add = add i32 %x, 9
1417  %cond = select i1 %cmp, i32 -1, i32 %add
1418  ret i32 %cond
1419}
1420
1421define i32 @uadd_sat_flipped3(i32 %x) {
1422; CHECK-LABEL: @uadd_sat_flipped3(
1423; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -8
1424; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[X]], 9
1425; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1426; CHECK-NEXT:    ret i32 [[COND]]
1427;
1428  %cmp = icmp ugt i32 %x, -8
1429  %add = add nuw i32 %x, 9
1430  %cond = select i1 %cmp, i32 -1, i32 %add
1431  ret i32 %cond
1432}
1433
1434; Negative Test
1435
1436define i32 @uadd_sat_flipped3_neg_no_nuw(i32 %x) {
1437; CHECK-LABEL: @uadd_sat_flipped3_neg_no_nuw(
1438; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -8
1439; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1440; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1441; CHECK-NEXT:    ret i32 [[COND]]
1442;
1443  %cmp = icmp ugt i32 %x, -8
1444  %add = add i32 %x, 9
1445  %cond = select i1 %cmp, i32 -1, i32 %add
1446  ret i32 %cond
1447}
1448
1449define i32 @uadd_sat_negative_one(i32 %x) {
1450; CHECK-LABEL: @uadd_sat_negative_one(
1451; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 1)
1452; CHECK-NEXT:    ret i32 [[COND]]
1453;
1454  %cmp = icmp eq i32 %x, -1
1455  %add = add i32 %x, 1
1456  %cond = select i1 %cmp, i32 -1, i32 %add
1457  ret i32 %cond
1458}
1459
1460define <2 x i8> @uadd_sat_flipped4_vector(<2 x i8> %x) {
1461; CHECK-LABEL: @uadd_sat_flipped4_vector(
1462; CHECK-NEXT:    [[COND:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 9))
1463; CHECK-NEXT:    ret <2 x i8> [[COND]]
1464;
1465  %cmp = icmp ult <2 x i8> %x, <i8 -10, i8 -10>
1466  %add = add <2 x i8> %x, <i8 9, i8 9>
1467  %cond = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> <i8 -1, i8 -1>
1468  ret <2 x i8> %cond
1469}
1470
1471define <2 x i8> @uadd_sat_flipped4_poison_vector(<2 x i8> %x) {
1472; CHECK-LABEL: @uadd_sat_flipped4_poison_vector(
1473; CHECK-NEXT:    [[COND:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 9))
1474; CHECK-NEXT:    ret <2 x i8> [[COND]]
1475;
1476  %cmp = icmp ult <2 x i8> %x, <i8 -10, i8 poison>
1477  %add = add <2 x i8> %x, <i8 9, i8 9>
1478  %cond = select <2 x i1> %cmp, <2 x i8> %add,<2 x i8> <i8 -1, i8 -1>
1479  ret <2 x i8> %cond
1480}
1481
1482define <2 x i8> @uadd_sat_flipped4_poison_vector_compare(<2 x i8> %x) {
1483; CHECK-LABEL: @uadd_sat_flipped4_poison_vector_compare(
1484; CHECK-NEXT:    [[COND:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 9))
1485; CHECK-NEXT:    ret <2 x i8> [[COND]]
1486;
1487  %cmp = icmp ult <2 x i8> %x, <i8 -10, i8 poison>
1488  %add = add <2 x i8> %x, <i8 9, i8 poison>
1489  %cond = select <2 x i1> %cmp, <2 x i8> %add,<2 x i8> <i8 -1, i8 -1>
1490  ret <2 x i8> %cond
1491}
1492
1493define <2 x i8> @uadd_sat_flipped4_poison_vector_compare2(<2 x i8> %x) {
1494; CHECK-LABEL: @uadd_sat_flipped4_poison_vector_compare2(
1495; CHECK-NEXT:    ret <2 x i8> splat (i8 -1)
1496;
1497  %cmp = icmp ult <2 x i8> %x, <i8 -10, i8 poison>
1498  %add = add <2 x i8> %x, <i8 poison, i8 poison>
1499  %cond = select <2 x i1> %cmp, <2 x i8> %add,<2 x i8> <i8 -1, i8 -1>
1500  ret <2 x i8> %cond
1501}
1502
1503; Negative test:
1504
1505define i32 @uadd_sat_flipped_too_big(i32 %x) {
1506; CHECK-LABEL: @uadd_sat_flipped_too_big(
1507; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -8
1508; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1509; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -1
1510; CHECK-NEXT:    ret i32 [[COND]]
1511;
1512  %cmp = icmp ult i32 %x, -8
1513  %add = add i32 %x, 9
1514  %cond = select i1 %cmp, i32 %add, i32 -1
1515  ret i32 %cond
1516}
1517
1518; Negative test:
1519
1520define i32 @uadd_sat_flipped_wrong_bounds(i32 %x) {
1521; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds(
1522; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -13
1523; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1524; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1525; CHECK-NEXT:    ret i32 [[COND]]
1526;
1527  %cmp = icmp uge i32 %x, -12
1528  %add = add i32 %x, 9
1529  %cond = select i1 %cmp, i32 -1, i32 %add
1530  ret i32 %cond
1531}
1532
1533; Negative test:
1534
1535define i32 @uadd_sat_flipped_wrong_bounds2(i32 %x) {
1536; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds2(
1537; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -12
1538; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1539; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1540; CHECK-NEXT:    ret i32 [[COND]]
1541;
1542  %cmp = icmp ugt i32 %x, -12
1543  %add = add i32 %x, 9
1544  %cond = select i1 %cmp, i32 -1, i32 %add
1545  ret i32 %cond
1546}
1547
1548; Negative test:
1549
1550define i32 @uadd_sat_flipped_wrong_bounds3(i32 %x) {
1551; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds3(
1552; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -12
1553; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1554; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1555; CHECK-NEXT:    ret i32 [[COND]]
1556;
1557  %cmp = icmp ugt i32 %x, -12
1558  %add = add i32 %x, 9
1559  %cond = select i1 %cmp, i32 -1, i32 %add
1560  ret i32 %cond
1561}
1562
1563; Negative test:
1564
1565define i32 @uadd_sat_flipped_wrong_bounds4(i32 %x) {
1566; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds4(
1567; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -9
1568; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1569; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
1570; CHECK-NEXT:    ret i32 [[COND]]
1571;
1572  %cmp = icmp uge i32 %x, -8
1573  %add = add i32 %x, 9
1574  %cond = select i1 %cmp, i32 -1, i32 %add
1575  ret i32 %cond
1576}
1577
1578; Negative test:
1579
1580define i32 @uadd_sat_flipped_wrong_bounds5(i32 %x) {
1581; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds5(
1582; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -8
1583; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1584; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -1
1585; CHECK-NEXT:    ret i32 [[COND]]
1586;
1587  %cmp = icmp ult i32 %x, -8
1588  %add = add i32 %x, 9
1589  %cond = select i1 %cmp, i32 %add, i32 -1
1590  ret i32 %cond
1591}
1592
1593; Negative test:
1594
1595define i32 @uadd_sat_flipped_wrong_bounds6(i32 %x) {
1596; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds6(
1597; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -11
1598; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1599; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -1
1600; CHECK-NEXT:    ret i32 [[COND]]
1601;
1602  %cmp = icmp ule i32 %x, -12
1603  %add = add i32 %x, 9
1604  %cond = select i1 %cmp, i32 %add, i32 -1
1605  ret i32 %cond
1606}
1607
1608; Negative test:
1609
1610define i32 @uadd_sat_flipped_wrong_bounds7(i32 %x) {
1611; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds7(
1612; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -11
1613; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1614; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -1
1615; CHECK-NEXT:    ret i32 [[COND]]
1616;
1617  %cmp = icmp ule i32 %x, -12
1618  %add = add i32 %x, 9
1619  %cond = select i1 %cmp, i32 %add, i32 -1
1620  ret i32 %cond
1621}
1622
1623; Negative test:
1624
1625define i32 @uadd_sat_flipped_wrong_bounds8(i32 %x) {
1626; CHECK-LABEL: @uadd_sat_flipped_wrong_bounds8(
1627; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -12
1628; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 9
1629; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -1
1630; CHECK-NEXT:    ret i32 [[COND]]
1631;
1632  %cmp = icmp ult i32 %x, -12
1633  %add = add i32 %x, 9
1634  %cond = select i1 %cmp, i32 %add, i32 -1
1635  ret i32 %cond
1636}
1637
1638define i32 @uadd_sat_nonstrict(i32 %x, i32 %y) {
1639; CHECK-LABEL: @uadd_sat_nonstrict(
1640; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
1641; CHECK-NEXT:    ret i32 [[R]]
1642;
1643  %notx = xor i32 %x, -1
1644  %a = add i32 %y, %x
1645  %c = icmp ule i32 %notx, %y
1646  %r = select i1 %c, i32 -1, i32 %a
1647  ret i32 %r
1648}
1649
1650define i32 @uadd_sat_commute_add(i32 %xp, i32 %y) {
1651; CHECK-LABEL: @uadd_sat_commute_add(
1652; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[XP:%.*]]
1653; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Y:%.*]])
1654; CHECK-NEXT:    ret i32 [[R]]
1655;
1656  %x = urem i32 42, %xp ; thwart complexity-based-canonicalization
1657  %notx = xor i32 %x, -1
1658  %a = add i32 %x, %y
1659  %c = icmp ult i32 %notx, %y
1660  %r = select i1 %c, i32 -1, i32 %a
1661  ret i32 %r
1662}
1663
1664define i32 @uadd_sat_ugt(i32 %x, i32 %yp) {
1665; CHECK-LABEL: @uadd_sat_ugt(
1666; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1667; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1668; CHECK-NEXT:    ret i32 [[R]]
1669;
1670  %y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1671  %notx = xor i32 %x, -1
1672  %a = add i32 %y, %x
1673  %c = icmp ugt i32 %y, %notx
1674  %r = select i1 %c, i32 -1, i32 %a
1675  ret i32 %r
1676}
1677define i32 @uadd_sat_uge(i32 %x, i32 %yp) {
1678; CHECK-LABEL: @uadd_sat_uge(
1679; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1680; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1681; CHECK-NEXT:    ret i32 [[R]]
1682;
1683  %y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1684  %notx = xor i32 %x, -1
1685  %a = add i32 %y, %x
1686  %c = icmp uge i32 %y, %notx
1687  %r = select i1 %c, i32 -1, i32 %a
1688  ret i32 %r
1689}
1690
1691define <2 x i32> @uadd_sat_ugt_commute_add(<2 x i32> %xp, <2 x i32> %yp) {
1692; CHECK-LABEL: @uadd_sat_ugt_commute_add(
1693; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i32> [[YP:%.*]], <i32 2442, i32 4242>
1694; CHECK-NEXT:    [[X:%.*]] = srem <2 x i32> <i32 42, i32 43>, [[XP:%.*]]
1695; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> [[X]], <2 x i32> [[Y]])
1696; CHECK-NEXT:    ret <2 x i32> [[R]]
1697;
1698  %y = sdiv <2 x i32> %yp, <i32 2442, i32 4242> ; thwart complexity-based-canonicalization
1699  %x = srem <2 x i32> <i32 42, i32 43>, %xp     ; thwart complexity-based-canonicalization
1700  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
1701  %a = add <2 x i32> %x, %y
1702  %c = icmp ugt <2 x i32> %y, %notx
1703  %r = select <2 x i1> %c, <2 x i32> <i32 -1, i32 -1>, <2 x i32> %a
1704  ret <2 x i32> %r
1705}
1706
1707define i32 @uadd_sat_commute_select(i32 %x, i32 %yp) {
1708; CHECK-LABEL: @uadd_sat_commute_select(
1709; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1710; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1711; CHECK-NEXT:    ret i32 [[R]]
1712;
1713  %y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1714  %notx = xor i32 %x, -1
1715  %a = add i32 %y, %x
1716  %c = icmp ult i32 %y, %notx
1717  %r = select i1 %c, i32 %a, i32 -1
1718  ret i32 %r
1719}
1720
1721define i32 @uadd_sat_commute_select_nonstrict(i32 %x, i32 %yp) {
1722; CHECK-LABEL: @uadd_sat_commute_select_nonstrict(
1723; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1724; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
1725; CHECK-NEXT:    ret i32 [[R]]
1726;
1727  %y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1728  %notx = xor i32 %x, -1
1729  %a = add i32 %y, %x
1730  %c = icmp ule i32 %y, %notx
1731  %r = select i1 %c, i32 %a, i32 -1
1732  ret i32 %r
1733}
1734
1735define i32 @uadd_sat_commute_select_commute_add(i32 %xp, i32 %yp) {
1736; CHECK-LABEL: @uadd_sat_commute_select_commute_add(
1737; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[XP:%.*]]
1738; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 [[YP:%.*]], 2442
1739; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Y]])
1740; CHECK-NEXT:    ret i32 [[R]]
1741;
1742  %x = urem i32 42, %xp ; thwart complexity-based-canonicalization
1743  %y = sdiv i32 %yp, 2442 ; thwart complexity-based-canonicalization
1744  %notx = xor i32 %x, -1
1745  %a = add i32 %x, %y
1746  %c = icmp ult i32 %y, %notx
1747  %r = select i1 %c, i32 %a, i32 -1
1748  ret i32 %r
1749}
1750
1751define <2 x i32> @uadd_sat_commute_select_ugt(<2 x i32> %x, <2 x i32> %y) {
1752; CHECK-LABEL: @uadd_sat_commute_select_ugt(
1753; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]])
1754; CHECK-NEXT:    ret <2 x i32> [[R]]
1755;
1756  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
1757  %a = add <2 x i32> %y, %x
1758  %c = icmp ugt <2 x i32> %notx, %y
1759  %r = select <2 x i1> %c, <2 x i32> %a, <2 x i32> <i32 -1, i32 -1>
1760  ret <2 x i32> %r
1761}
1762
1763define i32 @uadd_sat_commute_select_ugt_commute_add(i32 %xp, i32 %y) {
1764; CHECK-LABEL: @uadd_sat_commute_select_ugt_commute_add(
1765; CHECK-NEXT:    [[X:%.*]] = srem i32 42, [[XP:%.*]]
1766; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Y:%.*]])
1767; CHECK-NEXT:    ret i32 [[R]]
1768;
1769  %x = srem i32 42, %xp   ; thwart complexity-based-canonicalization
1770  %notx = xor i32 %x, -1
1771  %a = add i32 %x, %y
1772  %c = icmp ugt i32 %notx, %y
1773  %r = select i1 %c, i32 %a, i32 -1
1774  ret i32 %r
1775}
1776
1777; Negative test - make sure we have a -1 in the select.
1778
1779define i32 @not_uadd_sat(i32 %x, i32 %y) {
1780; CHECK-LABEL: @not_uadd_sat(
1781; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], -2
1782; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], 1
1783; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 [[Y:%.*]]
1784; CHECK-NEXT:    ret i32 [[R]]
1785;
1786  %a = add i32 %x, -2
1787  %c = icmp ugt i32 %x, 1
1788  %r = select i1 %c, i32 %a, i32 %y
1789  ret i32 %r
1790}
1791
1792; Negative test - make sure the predicate is 'ult'.
1793
1794define i32 @not_uadd_sat2(i32 %x, i32 %y) {
1795; CHECK-LABEL: @not_uadd_sat2(
1796; CHECK-NEXT:    [[X:%.*]] = call i32 @llvm.umax.i32(i32 [[X1:%.*]], i32 1)
1797; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], -2
1798; CHECK-NEXT:    ret i32 [[A]]
1799;
1800  %a = add i32 %x, -2
1801  %c = icmp ugt i32 %x, 1
1802  %r = select i1 %c, i32 %a, i32 -1
1803  ret i32 %r
1804}
1805
1806; The add may include a 'not' op rather than the cmp.
1807
1808define i32 @uadd_sat_not(i32 %x, i32 %y) {
1809; CHECK-LABEL: @uadd_sat_not(
1810; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1811; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1812; CHECK-NEXT:    ret i32 [[R]]
1813;
1814  %notx = xor i32 %x, -1
1815  %a = add i32 %notx, %y
1816  %c = icmp ult i32 %x, %y
1817  %r = select i1 %c, i32 -1, i32 %a
1818  ret i32 %r
1819}
1820
1821define i32 @uadd_sat_not_nonstrict(i32 %x, i32 %y) {
1822; CHECK-LABEL: @uadd_sat_not_nonstrict(
1823; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1824; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1825; CHECK-NEXT:    ret i32 [[R]]
1826;
1827  %notx = xor i32 %x, -1
1828  %a = add i32 %notx, %y
1829  %c = icmp ule i32 %x, %y
1830  %r = select i1 %c, i32 -1, i32 %a
1831  ret i32 %r
1832}
1833
1834define i32 @uadd_sat_not_commute_add(i32 %xp, i32 %yp) {
1835; CHECK-LABEL: @uadd_sat_not_commute_add(
1836; CHECK-NEXT:    [[X:%.*]] = srem i32 42, [[XP:%.*]]
1837; CHECK-NEXT:    [[Y:%.*]] = urem i32 42, [[YP:%.*]]
1838; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X]], -1
1839; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y]], i32 [[NOTX]])
1840; CHECK-NEXT:    ret i32 [[R]]
1841;
1842  %x = srem i32 42, %xp ; thwart complexity-based-canonicalization
1843  %y = urem i32 42, %yp ; thwart complexity-based-canonicalization
1844  %notx = xor i32 %x, -1
1845  %a = add i32 %y, %notx
1846  %c = icmp ult i32 %x, %y
1847  %r = select i1 %c, i32 -1, i32 %a
1848  ret i32 %r
1849}
1850
1851define i32 @uadd_sat_not_ugt(i32 %x, i32 %y) {
1852; CHECK-LABEL: @uadd_sat_not_ugt(
1853; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1854; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1855; CHECK-NEXT:    ret i32 [[R]]
1856;
1857  %notx = xor i32 %x, -1
1858  %a = add i32 %notx, %y
1859  %c = icmp ugt i32 %y, %x
1860  %r = select i1 %c, i32 -1, i32 %a
1861  ret i32 %r
1862}
1863
1864define i32 @uadd_sat_not_uge(i32 %x, i32 %y) {
1865; CHECK-LABEL: @uadd_sat_not_uge(
1866; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1867; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1868; CHECK-NEXT:    ret i32 [[R]]
1869;
1870  %notx = xor i32 %x, -1
1871  %a = add i32 %notx, %y
1872  %c = icmp uge i32 %y, %x
1873  %r = select i1 %c, i32 -1, i32 %a
1874  ret i32 %r
1875}
1876
1877define <2 x i32> @uadd_sat_not_ugt_commute_add(<2 x i32> %x, <2 x i32> %yp) {
1878; CHECK-LABEL: @uadd_sat_not_ugt_commute_add(
1879; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i32> [[YP:%.*]], <i32 2442, i32 4242>
1880; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[X:%.*]], splat (i32 -1)
1881; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> [[Y]], <2 x i32> [[NOTX]])
1882; CHECK-NEXT:    ret <2 x i32> [[R]]
1883;
1884  %y = sdiv <2 x i32> %yp, <i32 2442, i32 4242> ; thwart complexity-based-canonicalization
1885  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
1886  %a = add <2 x i32> %y, %notx
1887  %c = icmp ugt <2 x i32> %y, %x
1888  %r = select <2 x i1> %c, <2 x i32> <i32 -1, i32 -1>, <2 x i32> %a
1889  ret <2 x i32> %r
1890}
1891
1892define <2 x i32> @uadd_sat_not_ugt_commute_add_partial_poison(<2 x i32> %x, <2 x i32> %yp) {
1893; CHECK-LABEL: @uadd_sat_not_ugt_commute_add_partial_poison(
1894; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -1, i32 poison>
1895; CHECK-NEXT:    [[A:%.*]] = add nuw <2 x i32> [[YP:%.*]], [[NOTX]]
1896; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[YP]], [[X]]
1897; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> splat (i32 -1), <2 x i32> [[A]]
1898; CHECK-NEXT:    ret <2 x i32> [[R]]
1899;
1900  %notx = xor <2 x i32> %x, <i32 -1, i32 poison>
1901  %a = add nuw <2 x i32> %yp, %notx
1902  %c = icmp ugt <2 x i32> %yp, %x
1903  %r = select <2 x i1> %c, <2 x i32> <i32 -1, i32 -1>, <2 x i32> %a
1904  ret <2 x i32> %r
1905}
1906
1907define i32 @uadd_sat_not_commute_select(i32 %x, i32 %y) {
1908; CHECK-LABEL: @uadd_sat_not_commute_select(
1909; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1910; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1911; CHECK-NEXT:    ret i32 [[R]]
1912;
1913  %notx = xor i32 %x, -1
1914  %a = add i32 %notx, %y
1915  %c = icmp ult i32 %y, %x
1916  %r = select i1 %c, i32 %a, i32 -1
1917  ret i32 %r
1918}
1919
1920define i32 @uadd_sat_not_commute_select_nonstrict(i32 %x, i32 %y) {
1921; CHECK-LABEL: @uadd_sat_not_commute_select_nonstrict(
1922; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1923; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1924; CHECK-NEXT:    ret i32 [[R]]
1925;
1926  %notx = xor i32 %x, -1
1927  %a = add i32 %notx, %y
1928  %c = icmp ule i32 %y, %x
1929  %r = select i1 %c, i32 %a, i32 -1
1930  ret i32 %r
1931}
1932
1933define i32 @uadd_sat_not_commute_select_commute_add(i32 %x, i32 %yp) {
1934; CHECK-LABEL: @uadd_sat_not_commute_select_commute_add(
1935; CHECK-NEXT:    [[Y:%.*]] = sdiv i32 42, [[YP:%.*]]
1936; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1937; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y]], i32 [[NOTX]])
1938; CHECK-NEXT:    ret i32 [[R]]
1939;
1940  %y = sdiv i32 42, %yp ; thwart complexity-based-canonicalization
1941  %notx = xor i32 %x, -1
1942  %a = add i32 %y, %notx
1943  %c = icmp ult i32 %y, %x
1944  %r = select i1 %c, i32 %a, i32 -1
1945  ret i32 %r
1946}
1947
1948define <2 x i32> @uadd_sat_not_commute_select_ugt(<2 x i32> %xp, <2 x i32> %yp) {
1949; CHECK-LABEL: @uadd_sat_not_commute_select_ugt(
1950; CHECK-NEXT:    [[X:%.*]] = urem <2 x i32> <i32 42, i32 -42>, [[XP:%.*]]
1951; CHECK-NEXT:    [[Y:%.*]] = srem <2 x i32> <i32 12, i32 412>, [[YP:%.*]]
1952; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[X]], splat (i32 -1)
1953; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> [[Y]], <2 x i32> [[NOTX]])
1954; CHECK-NEXT:    ret <2 x i32> [[R]]
1955;
1956  %x = urem <2 x i32> <i32 42, i32 -42>, %xp ; thwart complexity-based-canonicalization
1957  %y = srem <2 x i32> <i32 12, i32 412>, %yp ; thwart complexity-based-canonicalization
1958  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
1959  %a = add <2 x i32> %y, %notx
1960  %c = icmp ugt <2 x i32> %x, %y
1961  %r = select <2 x i1> %c, <2 x i32> %a, <2 x i32> <i32 -1, i32 -1>
1962  ret <2 x i32> %r
1963}
1964
1965define i32 @uadd_sat_not_commute_select_ugt_commute_add(i32 %x, i32 %y) {
1966; CHECK-LABEL: @uadd_sat_not_commute_select_ugt_commute_add(
1967; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1968; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1969; CHECK-NEXT:    ret i32 [[R]]
1970;
1971  %notx = xor i32 %x, -1
1972  %a = add i32 %notx, %y
1973  %c = icmp ugt i32 %x, %y
1974  %r = select i1 %c, i32 %a, i32 -1
1975  ret i32 %r
1976}
1977
1978define i32 @uadd_sat_not_commute_select_uge_commute_add(i32 %x, i32 %y) {
1979; CHECK-LABEL: @uadd_sat_not_commute_select_uge_commute_add(
1980; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
1981; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[NOTX]])
1982; CHECK-NEXT:    ret i32 [[R]]
1983;
1984  %notx = xor i32 %x, -1
1985  %a = add i32 %notx, %y
1986  %c = icmp uge i32 %x, %y
1987  %r = select i1 %c, i32 %a, i32 -1
1988  ret i32 %r
1989}
1990
1991define i32 @uadd_sat_constant(i32 %x) {
1992; CHECK-LABEL: @uadd_sat_constant(
1993; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 42)
1994; CHECK-NEXT:    ret i32 [[R]]
1995;
1996  %a = add i32 %x, 42
1997  %c = icmp ugt i32 %x, -43
1998  %r = select i1 %c, i32 -1, i32 %a
1999  ret i32 %r
2000}
2001
2002define i32 @uadd_sat_constant_commute(i32 %x) {
2003; CHECK-LABEL: @uadd_sat_constant_commute(
2004; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 42)
2005; CHECK-NEXT:    ret i32 [[R]]
2006;
2007  %a = add i32 %x, 42
2008  %c = icmp ult i32 %x, -43
2009  %r = select i1 %c, i32 %a, i32 -1
2010  ret i32 %r
2011}
2012
2013define i32 @uadd_sat_canon(i32 %x, i32 %y) {
2014; CHECK-LABEL: @uadd_sat_canon(
2015; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y:%.*]])
2016; CHECK-NEXT:    ret i32 [[R]]
2017;
2018  %a = add i32 %x, %y
2019  %c = icmp ult i32 %a, %x
2020  %r = select i1 %c, i32 -1, i32 %a
2021  ret i32 %r
2022}
2023
2024define i32 @uadd_sat_canon_y(i32 %x, i32 %y) {
2025; CHECK-LABEL: @uadd_sat_canon_y(
2026; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
2027; CHECK-NEXT:    ret i32 [[R]]
2028;
2029  %a = add i32 %x, %y
2030  %c = icmp ult i32 %a, %y
2031  %r = select i1 %c, i32 -1, i32 %a
2032  ret i32 %r
2033}
2034
2035define i32 @uadd_sat_canon_nuw(i32 %x, i32 %y) {
2036; CHECK-LABEL: @uadd_sat_canon_nuw(
2037; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
2038; CHECK-NEXT:    ret i32 [[A]]
2039;
2040  %a = add nuw i32 %x, %y
2041  %c = icmp ult i32 %a, %x
2042  %r = select i1 %c, i32 -1, i32 %a
2043  ret i32 %r
2044}
2045
2046define i32 @uadd_sat_canon_y_nuw(i32 %x, i32 %y) {
2047; CHECK-LABEL: @uadd_sat_canon_y_nuw(
2048; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
2049; CHECK-NEXT:    ret i32 [[A]]
2050;
2051  %a = add nuw i32 %x, %y
2052  %c = icmp ult i32 %a, %y
2053  %r = select i1 %c, i32 -1, i32 %a
2054  ret i32 %r
2055}
2056
2057define <4 x i32> @uadd_sat_constant_vec(<4 x i32> %x) {
2058; CHECK-LABEL: @uadd_sat_constant_vec(
2059; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> [[X:%.*]], <4 x i32> splat (i32 42))
2060; CHECK-NEXT:    ret <4 x i32> [[R]]
2061;
2062  %a = add <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42>
2063  %c = icmp ugt <4 x i32> %x, <i32 -43, i32 -43, i32 -43, i32 -43>
2064  %r = select <4 x i1> %c, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> %a
2065  ret <4 x i32> %r
2066}
2067
2068define <4 x i32> @uadd_sat_constant_vec_commute(<4 x i32> %x) {
2069; CHECK-LABEL: @uadd_sat_constant_vec_commute(
2070; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> [[X:%.*]], <4 x i32> splat (i32 42))
2071; CHECK-NEXT:    ret <4 x i32> [[R]]
2072;
2073  %a = add <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42>
2074  %c = icmp ult <4 x i32> %x, <i32 -43, i32 -43, i32 -43, i32 -43>
2075  %r = select <4 x i1> %c, <4 x i32> %a, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
2076  ret <4 x i32> %r
2077}
2078
2079define <4 x i32> @uadd_sat_constant_vec_commute_undefs(<4 x i32> %x) {
2080; CHECK-LABEL: @uadd_sat_constant_vec_commute_undefs(
2081; CHECK-NEXT:    [[R:%.*]] = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> [[X:%.*]], <4 x i32> splat (i32 42))
2082; CHECK-NEXT:    ret <4 x i32> [[R]]
2083;
2084  %a = add <4 x i32> %x, <i32 42, i32 42, i32 42, i32 poison>
2085  %c = icmp ult <4 x i32> %x, <i32 -43, i32 -43, i32 poison, i32 -43>
2086  %r = select <4 x i1> %c, <4 x i32> %a, <4 x i32> <i32 -1, i32 poison, i32 -1, i32 -1>
2087  ret <4 x i32> %r
2088}
2089
2090declare i32 @get_i32()
2091declare <2 x i8> @get_v2i8()
2092
2093define i32 @unsigned_sat_variable_using_min_add(i32 %x) {
2094; CHECK-LABEL: @unsigned_sat_variable_using_min_add(
2095; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
2096; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
2097; CHECK-NEXT:    ret i32 [[R]]
2098;
2099  %y = call i32 @get_i32() ; thwart complexity-based canonicalization
2100  %noty = xor i32 %y, -1
2101  %c = icmp ult i32 %x, %noty
2102  %s = select i1 %c, i32 %x, i32 %noty
2103  %r = add i32 %s, %y
2104  ret i32 %r
2105}
2106
2107define i32 @unsigned_sat_variable_using_min_commute_add(i32 %x) {
2108; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_add(
2109; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
2110; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 [[Y]])
2111; CHECK-NEXT:    ret i32 [[R]]
2112;
2113  %y = call i32 @get_i32() ; thwart complexity-based canonicalization
2114  %noty = xor i32 %y, -1
2115  %c = icmp ult i32 %x, %noty
2116  %s = select i1 %c, i32 %x, i32 %noty
2117  %r = add i32 %y, %s
2118  ret i32 %r
2119}
2120
2121define <2 x i8> @unsigned_sat_variable_using_min_commute_select(<2 x i8> %x) {
2122; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_select(
2123; CHECK-NEXT:    [[Y:%.*]] = call <2 x i8> @get_v2i8()
2124; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y]])
2125; CHECK-NEXT:    ret <2 x i8> [[R]]
2126;
2127  %y = call <2 x i8> @get_v2i8() ; thwart complexity-based canonicalization
2128  %noty = xor <2 x i8> %y, <i8 -1, i8 -1>
2129  %c = icmp ult <2 x i8> %noty, %x
2130  %s = select <2 x i1> %c, <2 x i8> %noty, <2 x i8> %x
2131  %r = add <2 x i8> %s, %y
2132  ret <2 x i8> %r
2133}
2134
2135define <2 x i8> @unsigned_sat_variable_using_min_commute_add_select(<2 x i8> %x) {
2136; CHECK-LABEL: @unsigned_sat_variable_using_min_commute_add_select(
2137; CHECK-NEXT:    [[Y:%.*]] = call <2 x i8> @get_v2i8()
2138; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y]])
2139; CHECK-NEXT:    ret <2 x i8> [[R]]
2140;
2141  %y = call <2 x i8> @get_v2i8() ; thwart complexity-based canonicalization
2142  %noty = xor <2 x i8> %y, <i8 -1, i8 -1>
2143  %c = icmp ult <2 x i8> %noty, %x
2144  %s = select <2 x i1> %c, <2 x i8> %noty, <2 x i8> %x
2145  %r = add <2 x i8> %y, %s
2146  ret <2 x i8> %r
2147}
2148
2149; Negative test
2150
2151define i32 @unsigned_sat_variable_using_wrong_min(i32 %x) {
2152; CHECK-LABEL: @unsigned_sat_variable_using_wrong_min(
2153; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
2154; CHECK-NEXT:    [[NOTY:%.*]] = xor i32 [[Y]], -1
2155; CHECK-NEXT:    [[S:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[NOTY]])
2156; CHECK-NEXT:    [[R:%.*]] = add i32 [[Y]], [[S]]
2157; CHECK-NEXT:    ret i32 [[R]]
2158;
2159  %y = call i32 @get_i32() ; thwart complexity-based canonicalization
2160  %noty = xor i32 %y, -1
2161  %c = icmp slt i32 %x, %noty
2162  %s = select i1 %c, i32 %x, i32 %noty
2163  %r = add i32 %y, %s
2164  ret i32 %r
2165}
2166
2167; Negative test
2168
2169define i32 @unsigned_sat_variable_using_wrong_value(i32 %x, i32 %z) {
2170; CHECK-LABEL: @unsigned_sat_variable_using_wrong_value(
2171; CHECK-NEXT:    [[Y:%.*]] = call i32 @get_i32()
2172; CHECK-NEXT:    [[NOTY:%.*]] = xor i32 [[Y]], -1
2173; CHECK-NEXT:    [[S:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[NOTY]])
2174; CHECK-NEXT:    [[R:%.*]] = add i32 [[Z:%.*]], [[S]]
2175; CHECK-NEXT:    ret i32 [[R]]
2176;
2177  %y = call i32 @get_i32() ; thwart complexity-based canonicalization
2178  %noty = xor i32 %y, -1
2179  %c = icmp ult i32 %x, %noty
2180  %s = select i1 %c, i32 %x, i32 %noty
2181  %r = add i32 %z, %s
2182  ret i32 %r
2183}
2184
2185; If we have a constant operand, there's no commutativity variation.
2186
2187define i32 @unsigned_sat_constant_using_min(i32 %x) {
2188; CHECK-LABEL: @unsigned_sat_constant_using_min(
2189; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X:%.*]], i32 -43)
2190; CHECK-NEXT:    ret i32 [[R]]
2191;
2192  %c = icmp ult i32 %x, 42
2193  %s = select i1 %c, i32 %x, i32 42
2194  %r = add i32 %s, -43
2195  ret i32 %r
2196}
2197
2198define <2 x i32> @unsigned_sat_constant_using_min_splat(<2 x i32> %x) {
2199; CHECK-LABEL: @unsigned_sat_constant_using_min_splat(
2200; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 -15))
2201; CHECK-NEXT:    ret <2 x i32> [[R]]
2202;
2203  %c = icmp ult <2 x i32> %x, <i32 14, i32 14>
2204  %s = select <2 x i1> %c, <2 x i32> %x, <2 x i32> <i32 14, i32 14>
2205  %r = add <2 x i32> %s, <i32 -15, i32 -15>
2206  ret <2 x i32> %r
2207}
2208
2209; Negative test
2210
2211define i32 @unsigned_sat_constant_using_min_wrong_constant(i32 %x) {
2212; CHECK-LABEL: @unsigned_sat_constant_using_min_wrong_constant(
2213; CHECK-NEXT:    [[S:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 42)
2214; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[S]], -42
2215; CHECK-NEXT:    ret i32 [[R]]
2216;
2217  %c = icmp ult i32 %x, 42
2218  %s = select i1 %c, i32 %x, i32 42
2219  %r = add i32 %s, -42
2220  ret i32 %r
2221}
2222
2223define i32 @uadd_sat_via_add(i32 %x, i32 %y) {
2224; CHECK-LABEL: @uadd_sat_via_add(
2225; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
2226; CHECK-NEXT:    ret i32 [[R]]
2227;
2228  %a = add i32 %x, %y
2229  %c = icmp ult i32 %a, %y
2230  %r = select i1 %c, i32 -1, i32 %a
2231  ret i32 %r
2232}
2233
2234define i32 @uadd_sat_via_add_nonstrict(i32 %x, i32 %y) {
2235; CHECK-LABEL: @uadd_sat_via_add_nonstrict(
2236; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
2237; CHECK-NEXT:    [[C_NOT:%.*]] = icmp ugt i32 [[A]], [[Y]]
2238; CHECK-NEXT:    [[R:%.*]] = select i1 [[C_NOT]], i32 [[A]], i32 -1
2239; CHECK-NEXT:    ret i32 [[R]]
2240;
2241  %a = add i32 %x, %y
2242  %c = icmp ule i32 %a, %y
2243  %r = select i1 %c, i32 -1, i32 %a
2244  ret i32 %r
2245}
2246
2247define i32 @uadd_sat_via_add_swapped_select(i32 %x, i32 %y) {
2248; CHECK-LABEL: @uadd_sat_via_add_swapped_select(
2249; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
2250; CHECK-NEXT:    ret i32 [[R]]
2251;
2252  %a = add i32 %x, %y
2253  %c = icmp uge i32 %a, %y
2254  %r = select i1 %c, i32 %a, i32 -1
2255  ret i32 %r
2256}
2257
2258define i32 @uadd_sat_via_add_swapped_select_strict(i32 %x, i32 %y) {
2259; CHECK-LABEL: @uadd_sat_via_add_swapped_select_strict(
2260; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
2261; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A]], [[Y]]
2262; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 -1
2263; CHECK-NEXT:    ret i32 [[R]]
2264;
2265  %a = add i32 %x, %y
2266  %c = icmp ugt i32 %a, %y
2267  %r = select i1 %c, i32 %a, i32 -1
2268  ret i32 %r
2269}
2270
2271define i32 @uadd_sat_via_add_swapped_cmp(i32 %x, i32 %y) {
2272; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp(
2273; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
2274; CHECK-NEXT:    ret i32 [[R]]
2275;
2276  %a = add i32 %x, %y
2277  %c = icmp ugt i32 %y, %a
2278  %r = select i1 %c, i32 -1, i32 %a
2279  ret i32 %r
2280}
2281
2282define i32 @uadd_sat_via_add_swapped_cmp_nonstrict(i32 %x, i32 %y) {
2283; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_nonstrict(
2284; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
2285; CHECK-NEXT:    [[C_NOT:%.*]] = icmp ult i32 [[Y]], [[A]]
2286; CHECK-NEXT:    [[R:%.*]] = select i1 [[C_NOT]], i32 [[A]], i32 -1
2287; CHECK-NEXT:    ret i32 [[R]]
2288;
2289  %a = add i32 %x, %y
2290  %c = icmp uge i32 %y, %a
2291  %r = select i1 %c, i32 -1, i32 %a
2292  ret i32 %r
2293}
2294
2295define i32 @uadd_sat_via_add_swapped_cmp_nonstric(i32 %x, i32 %y) {
2296; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_nonstric(
2297; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
2298; CHECK-NEXT:    ret i32 [[R]]
2299;
2300  %a = add i32 %x, %y
2301  %c = icmp ule i32 %y, %a
2302  %r = select i1 %c, i32 %a, i32 -1
2303  ret i32 %r
2304}
2305
2306define i32 @uadd_sat_via_add_swapped_cmp_select_nonstrict(i32 %x, i32 %y) {
2307; CHECK-LABEL: @uadd_sat_via_add_swapped_cmp_select_nonstrict(
2308; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
2309; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[Y]], [[A]]
2310; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 -1
2311; CHECK-NEXT:    ret i32 [[R]]
2312;
2313  %a = add i32 %x, %y
2314  %c = icmp ult i32 %y, %a
2315  %r = select i1 %c, i32 %a, i32 -1
2316  ret i32 %r
2317}
2318
2319define i8 @fold_add_umax_to_usub(i8 %a) {
2320; CHECK-LABEL: @fold_add_umax_to_usub(
2321; CHECK-NEXT:    [[SEL:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
2322; CHECK-NEXT:    ret i8 [[SEL]]
2323;
2324  %umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
2325  %sel = add i8 %umax, -10
2326  ret i8 %sel
2327}
2328
2329define i8 @fold_add_umax_to_usub_incorrect_rhs(i8 %a) {
2330; CHECK-LABEL: @fold_add_umax_to_usub_incorrect_rhs(
2331; CHECK-NEXT:    [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
2332; CHECK-NEXT:    [[SEL:%.*]] = add i8 [[UMAX]], -11
2333; CHECK-NEXT:    ret i8 [[SEL]]
2334;
2335  %umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
2336  %sel = add i8 %umax, -11
2337  ret i8 %sel
2338}
2339
2340define i8 @fold_add_umax_to_usub_multiuse(i8 %a) {
2341; CHECK-LABEL: @fold_add_umax_to_usub_multiuse(
2342; CHECK-NEXT:    [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A:%.*]], i8 10)
2343; CHECK-NEXT:    call void @usei8(i8 [[UMAX]])
2344; CHECK-NEXT:    [[SEL:%.*]] = add i8 [[UMAX]], -10
2345; CHECK-NEXT:    ret i8 [[SEL]]
2346;
2347  %umax = call i8 @llvm.umax.i8(i8 %a, i8 10)
2348  call void @usei8(i8 %umax)
2349  %sel = add i8 %umax, -10
2350  ret i8 %sel
2351}
2352
2353declare void @usei8(i8)
2354