xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; Tests for InstCombineCompares.cpp::foldICmpUSubSatOrUAddSatWithConstant
5; - usub_sat case
6; https://github.com/llvm/llvm-project/issues/58342
7
8; ==============================================================================
9; Basic tests with one user and positive arguments
10; ==============================================================================
11define i1 @icmp_eq_basic_positive(i8 %arg) {
12; CHECK-LABEL: define i1 @icmp_eq_basic_positive
13; CHECK-SAME: (i8 [[ARG:%.*]]) {
14; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ARG]], 7
15; CHECK-NEXT:    ret i1 [[CMP]]
16;
17  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 2)
18  %cmp = icmp eq i8 %sub, 5
19  ret i1 %cmp
20}
21
22define i1 @icmp_ne_basic_positive(i16 %arg) {
23; CHECK-LABEL: define i1 @icmp_ne_basic_positive
24; CHECK-SAME: (i16 [[ARG:%.*]]) {
25; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[ARG]], 17
26; CHECK-NEXT:    ret i1 [[CMP]]
27;
28  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 8)
29  %cmp = icmp ne i16 %sub, 9
30  ret i1 %cmp
31}
32
33define i1 @icmp_ule_basic_positive(i32 %arg) {
34; CHECK-LABEL: define i1 @icmp_ule_basic_positive
35; CHECK-SAME: (i32 [[ARG:%.*]]) {
36; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ARG]], 10
37; CHECK-NEXT:    ret i1 [[CMP]]
38;
39  %sub = call i32 @llvm.usub.sat.i32(i32 %arg, i32 6)
40  %cmp = icmp ule i32 %sub, 3
41  ret i1 %cmp
42}
43
44define i1 @icmp_ult_basic_positive(i64 %arg) {
45; CHECK-LABEL: define i1 @icmp_ult_basic_positive
46; CHECK-SAME: (i64 [[ARG:%.*]]) {
47; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[ARG]], 7
48; CHECK-NEXT:    ret i1 [[CMP]]
49;
50  %sub = call i64 @llvm.usub.sat.i64(i64 %arg, i64 5)
51  %cmp = icmp ult i64 %sub, 2
52  ret i1 %cmp
53}
54
55define i1 @icmp_uge_basic_positive(i8 %arg) {
56; CHECK-LABEL: define i1 @icmp_uge_basic_positive
57; CHECK-SAME: (i8 [[ARG:%.*]]) {
58; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[ARG]], 7
59; CHECK-NEXT:    ret i1 [[CMP]]
60;
61  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 4)
62  %cmp = icmp uge i8 %sub, 4
63  ret i1 %cmp
64}
65
66define i1 @icmp_ugt_basic_positive(i16 %arg) {
67; CHECK-LABEL: define i1 @icmp_ugt_basic_positive
68; CHECK-SAME: (i16 [[ARG:%.*]]) {
69; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ARG]], 4
70; CHECK-NEXT:    ret i1 [[CMP]]
71;
72  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 1)
73  %cmp = icmp ugt i16 %sub, 3
74  ret i1 %cmp
75}
76
77define i1 @icmp_sle_basic_positive(i32 %arg) {
78; CHECK-LABEL: define i1 @icmp_sle_basic_positive
79; CHECK-SAME: (i32 [[ARG:%.*]]) {
80; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[ARG]], 2147483638
81; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], -2147483639
82; CHECK-NEXT:    ret i1 [[CMP]]
83;
84  %sub = call i32 @llvm.usub.sat.i32(i32 %arg, i32 10)
85  %cmp = icmp sle i32 %sub, 8
86  ret i1 %cmp
87}
88
89define i1 @icmp_slt_basic_positive(i64 %arg) {
90; CHECK-LABEL: define i1 @icmp_slt_basic_positive
91; CHECK-SAME: (i64 [[ARG:%.*]]) {
92; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ARG]], 9223372036854775784
93; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[TMP1]], -9223372036854775803
94; CHECK-NEXT:    ret i1 [[CMP]]
95;
96  %sub = call i64 @llvm.usub.sat.i64(i64 %arg, i64 24)
97  %cmp = icmp slt i64 %sub, 5
98  ret i1 %cmp
99}
100
101define i1 @icmp_sge_basic_positive(i8 %arg) {
102; CHECK-LABEL: define i1 @icmp_sge_basic_positive
103; CHECK-SAME: (i8 [[ARG:%.*]]) {
104; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[ARG]], -5
105; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[TMP1]], 124
106; CHECK-NEXT:    ret i1 [[CMP]]
107;
108  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 1)
109  %cmp = icmp sge i8 %sub, 4
110  ret i1 %cmp
111}
112
113define i1 @icmp_sgt_basic_positive(i16 %arg) {
114; CHECK-LABEL: define i1 @icmp_sgt_basic_positive
115; CHECK-SAME: (i16 [[ARG:%.*]]) {
116; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ARG]], -8
117; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i16 [[TMP1]], 32762
118; CHECK-NEXT:    ret i1 [[CMP]]
119;
120  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 2)
121  %cmp = icmp sgt i16 %sub, 5
122  ret i1 %cmp
123}
124
125; ==============================================================================
126; Basic tests with one user and negative arguments
127; ==============================================================================
128define i1 @icmp_eq_basic_negative(i8 %arg) {
129; CHECK-LABEL: define i1 @icmp_eq_basic_negative
130; CHECK-SAME: (i8 [[ARG:%.*]]) {
131; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ARG]], -15
132; CHECK-NEXT:    ret i1 [[CMP]]
133;
134  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 -20)
135  %cmp = icmp eq i8 %sub, 5
136  ret i1 %cmp
137}
138
139define i1 @icmp_ne_basic_negative(i16 %arg) {
140; CHECK-LABEL: define i1 @icmp_ne_basic_negative
141; CHECK-SAME: (i16 [[ARG:%.*]]) {
142; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[ARG]], -71
143; CHECK-NEXT:    ret i1 [[CMP]]
144;
145  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 -80)
146  %cmp = icmp ne i16 %sub, 9
147  ret i1 %cmp
148}
149
150define i1 @icmp_ule_basic_negative(i32 %arg) {
151; CHECK-LABEL: define i1 @icmp_ule_basic_negative
152; CHECK-SAME: (i32 [[ARG:%.*]]) {
153; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ARG]], -2
154; CHECK-NEXT:    ret i1 [[CMP]]
155;
156  %sub = call i32 @llvm.usub.sat.i32(i32 %arg, i32 -6)
157  %cmp = icmp ule i32 %sub, 3
158  ret i1 %cmp
159}
160
161define i1 @icmp_ult_basic_negative(i64 %arg) {
162; CHECK-LABEL: define i1 @icmp_ult_basic_negative
163; CHECK-SAME: (i64 [[ARG:%.*]]) {
164; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[ARG]], -8
165; CHECK-NEXT:    ret i1 [[CMP]]
166;
167  %sub = call i64 @llvm.usub.sat.i64(i64 %arg, i64 -10)
168  %cmp = icmp ult i64 %sub, 2
169  ret i1 %cmp
170}
171
172define i1 @icmp_uge_basic_negative(i8 %arg) {
173; CHECK-LABEL: define i1 @icmp_uge_basic_negative
174; CHECK-SAME: (i8 [[ARG:%.*]]) {
175; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[ARG]], -3
176; CHECK-NEXT:    ret i1 [[CMP]]
177;
178  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 -4)
179  %cmp = icmp uge i8 %sub, 2
180  ret i1 %cmp
181}
182
183define i1 @icmp_ugt_basic_negative(i16 %arg) {
184; CHECK-LABEL: define i1 @icmp_ugt_basic_negative
185; CHECK-SAME: (i16 [[ARG:%.*]]) {
186; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ARG]], -7
187; CHECK-NEXT:    ret i1 [[CMP]]
188;
189  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 -10)
190  %cmp = icmp ugt i16 %sub, 3
191  ret i1 %cmp
192}
193
194define i1 @icmp_sle_basic_negative(i32 %arg) {
195; CHECK-LABEL: define i1 @icmp_sle_basic_negative
196; CHECK-SAME: (i32 [[ARG:%.*]]) {
197; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ARG]], -1
198; CHECK-NEXT:    ret i1 [[CMP]]
199;
200  %sub = call i32 @llvm.usub.sat.i32(i32 %arg, i32 -10)
201  %cmp = icmp sle i32 %sub, 8
202  ret i1 %cmp
203}
204
205define i1 @icmp_slt_basic_negative(i64 %arg) {
206; CHECK-LABEL: define i1 @icmp_slt_basic_negative
207; CHECK-SAME: (i64 [[ARG:%.*]]) {
208; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[ARG]], -19
209; CHECK-NEXT:    ret i1 [[CMP]]
210;
211  %sub = call i64 @llvm.usub.sat.i64(i64 %arg, i64 -24)
212  %cmp = icmp slt i64 %sub, 5
213  ret i1 %cmp
214}
215
216define i1 @icmp_sge_basic_negative(i8 %arg) {
217; CHECK-LABEL: define i1 @icmp_sge_basic_negative
218; CHECK-SAME: (i8 [[ARG:%.*]]) {
219; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[ARG]], -7
220; CHECK-NEXT:    ret i1 [[CMP]]
221;
222  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 -10)
223  %cmp = icmp sge i8 %sub, 4
224  ret i1 %cmp
225}
226
227define i1 @icmp_sgt_basic_negative(i16 %arg) {
228; CHECK-LABEL: define i1 @icmp_sgt_basic_negative
229; CHECK-SAME: (i16 [[ARG:%.*]]) {
230; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i16 [[ARG]], -15
231; CHECK-NEXT:    ret i1 [[CMP]]
232;
233  %sub = call i16 @llvm.usub.sat.i16(i16 %arg, i16 -20)
234  %cmp = icmp sgt i16 %sub, 5
235  ret i1 %cmp
236}
237
238; ==============================================================================
239; Tests with more than user and positive arguments
240; ==============================================================================
241define i1 @icmp_eq_multiuse_positive(i8 %arg) {
242; CHECK-LABEL: define i1 @icmp_eq_multiuse_positive
243; CHECK-SAME: (i8 [[ARG:%.*]]) {
244; CHECK-NEXT:    [[SUB:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[ARG]], i8 2)
245; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[SUB]], 5
246; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
247; CHECK-NEXT:    ret i1 [[CMP]]
248;
249  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 2)
250  %cmp = icmp eq i8 %sub, 5
251  call void @use.i8(i8 %sub)
252  ret i1 %cmp
253}
254
255; ==============================================================================
256; Tests with more than one user and negative arguments
257; ==============================================================================
258define i1 @icmp_eq_multiuse_negative(i8 %arg) {
259; CHECK-LABEL: define i1 @icmp_eq_multiuse_negative
260; CHECK-SAME: (i8 [[ARG:%.*]]) {
261; CHECK-NEXT:    [[SUB:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[ARG]], i8 -2)
262; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ARG]], -1
263; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
264; CHECK-NEXT:    ret i1 [[CMP]]
265;
266  %sub = call i8 @llvm.usub.sat.i8(i8 %arg, i8 -2)
267  %cmp = icmp eq i8 %sub, 1
268  call void @use.i8(i8 %sub)
269  ret i1 %cmp
270}
271
272; ==============================================================================
273; Tests with vector types and positive arguments
274; ==============================================================================
275define <2 x i1> @icmp_eq_vector_positive_equal(<2 x i8> %arg) {
276; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_positive_equal
277; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
278; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[ARG]], splat (i8 7)
279; CHECK-NEXT:    ret <2 x i1> [[CMP]]
280;
281  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 2, i8 2>)
282  %cmp = icmp eq <2 x i8> %sub, <i8 5, i8 5>
283  ret <2 x i1> %cmp
284}
285
286define <2 x i1> @icmp_eq_vector_positive_unequal(<2 x i8> %arg) {
287; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_positive_unequal
288; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
289; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[ARG]], <2 x i8> <i8 1, i8 2>)
290; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[SUB]], <i8 5, i8 6>
291; CHECK-NEXT:    ret <2 x i1> [[CMP]]
292;
293  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 1, i8 2>)
294  %cmp = icmp eq <2 x i8> %sub, <i8 5, i8 6>
295  ret <2 x i1> %cmp
296}
297
298define <2 x i1> @icmp_ne_vector_positive_equal(<2 x i16> %arg) {
299; CHECK-LABEL: define <2 x i1> @icmp_ne_vector_positive_equal
300; CHECK-SAME: (<2 x i16> [[ARG:%.*]]) {
301; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i16> [[ARG]], splat (i16 37)
302; CHECK-NEXT:    ret <2 x i1> [[CMP]]
303;
304  %sub = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %arg, <2 x i16> <i16 32, i16 32>)
305  %cmp = icmp ne <2 x i16> %sub, <i16 5, i16 5>
306  ret <2 x i1> %cmp
307}
308
309define <2 x i1> @icmp_ne_vector_positive_unequal(<2 x i16> %arg) {
310; CHECK-LABEL: define <2 x i1> @icmp_ne_vector_positive_unequal
311; CHECK-SAME: (<2 x i16> [[ARG:%.*]]) {
312; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> [[ARG]], <2 x i16> <i16 3, i16 33>)
313; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i16> [[SUB]], <i16 7, i16 6>
314; CHECK-NEXT:    ret <2 x i1> [[CMP]]
315;
316  %sub = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %arg, <2 x i16> <i16 3, i16 33>)
317  %cmp = icmp ne <2 x i16> %sub, <i16 7, i16 6>
318  ret <2 x i1> %cmp
319}
320
321define <2 x i1> @icmp_ule_vector_positive_equal(<2 x i32> %arg) {
322; CHECK-LABEL: define <2 x i1> @icmp_ule_vector_positive_equal
323; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) {
324; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[ARG]], splat (i32 37)
325; CHECK-NEXT:    ret <2 x i1> [[CMP]]
326;
327  %sub = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %arg, <2 x i32> <i32 32, i32 32>)
328  %cmp = icmp ult <2 x i32> %sub, <i32 5, i32 5>
329  ret <2 x i1> %cmp
330}
331
332define <2 x i1> @icmp_ule_vector_positive_unequal(<2 x i32> %arg) {
333; CHECK-LABEL: define <2 x i1> @icmp_ule_vector_positive_unequal
334; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) {
335; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> [[ARG]], <2 x i32> <i32 3, i32 35>)
336; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[SUB]], <i32 5, i32 7>
337; CHECK-NEXT:    ret <2 x i1> [[CMP]]
338;
339  %sub = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %arg, <2 x i32> <i32 3, i32 35>)
340  %cmp = icmp ult <2 x i32> %sub, <i32 5, i32 7>
341  ret <2 x i1> %cmp
342}
343
344define <2 x i1> @icmp_sgt_vector_positive_equal(<2 x i64> %arg) {
345; CHECK-LABEL: define <2 x i1> @icmp_sgt_vector_positive_equal
346; CHECK-SAME: (<2 x i64> [[ARG:%.*]]) {
347; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[ARG]], splat (i64 -410858)
348; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i64> [[TMP1]], splat (i64 9223372036854774573)
349; CHECK-NEXT:    ret <2 x i1> [[CMP]]
350;
351  %sub = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %arg, <2 x i64> <i64 409623, i64 409623>)
352  %cmp = icmp sgt <2 x i64> %sub, <i64 1234, i64 1234>
353  ret <2 x i1> %cmp
354}
355
356define <2 x i1> @icmp_sgt_vector_positive_unequal(<2 x i64> %arg) {
357; CHECK-LABEL: define <2 x i1> @icmp_sgt_vector_positive_unequal
358; CHECK-SAME: (<2 x i64> [[ARG:%.*]]) {
359; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> [[ARG]], <2 x i64> <i64 320498, i64 409623>)
360; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i64> [[SUB]], <i64 1234, i64 3456>
361; CHECK-NEXT:    ret <2 x i1> [[CMP]]
362;
363  %sub = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %arg, <2 x i64> <i64 320498, i64 409623>)
364  %cmp = icmp sgt <2 x i64> %sub, <i64 1234, i64 3456>
365  ret <2 x i1> %cmp
366}
367
368; ==============================================================================
369; Tests with vector types and negative arguments
370; ==============================================================================
371define <2 x i1> @icmp_eq_vector_negative_equal(<2 x i8> %arg) {
372; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_negative_equal
373; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
374; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[ARG]], splat (i8 -3)
375; CHECK-NEXT:    ret <2 x i1> [[CMP]]
376;
377  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 -5, i8 -5>)
378  %cmp = icmp eq <2 x i8> %sub, <i8 2, i8 2>
379  ret <2 x i1> %cmp
380}
381
382define <2 x i1> @icmp_eq_vector_negative_unequal(<2 x i8> %arg) {
383; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_negative_unequal
384; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
385; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[ARG]], <2 x i8> <i8 -10, i8 -20>)
386; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[SUB]], <i8 5, i8 6>
387; CHECK-NEXT:    ret <2 x i1> [[CMP]]
388;
389  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 -10, i8 -20>)
390  %cmp = icmp eq <2 x i8> %sub, <i8 5, i8 6>
391  ret <2 x i1> %cmp
392}
393
394; ==============================================================================
395; Tests with vector types, multiple uses and positive arguments
396; ==============================================================================
397define <2 x i1> @icmp_eq_vector_multiuse_positive_equal(<2 x i8> %arg) {
398; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_multiuse_positive_equal
399; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
400; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[ARG]], <2 x i8> splat (i8 2))
401; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[SUB]], splat (i8 5)
402; CHECK-NEXT:    call void @use.v2i8(<2 x i8> [[SUB]])
403; CHECK-NEXT:    ret <2 x i1> [[CMP]]
404;
405  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 2, i8 2>)
406  %cmp = icmp eq <2 x i8> %sub, <i8 5, i8 5>
407  call void @use.v2i8(<2 x i8> %sub)
408  ret <2 x i1> %cmp
409}
410
411; ==============================================================================
412; Tests with vector types, multiple uses and negative arguments
413; ==============================================================================
414define <2 x i1> @icmp_eq_vector_multiuse_negative_equal(<2 x i8> %arg) {
415; CHECK-LABEL: define <2 x i1> @icmp_eq_vector_multiuse_negative_equal
416; CHECK-SAME: (<2 x i8> [[ARG:%.*]]) {
417; CHECK-NEXT:    [[SUB:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[ARG]], <2 x i8> splat (i8 -20))
418; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[SUB]], splat (i8 5)
419; CHECK-NEXT:    call void @use.v2i8(<2 x i8> [[SUB]])
420; CHECK-NEXT:    ret <2 x i1> [[CMP]]
421;
422  %sub = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %arg, <2 x i8> <i8 -20, i8 -20>)
423  %cmp = icmp eq <2 x i8> %sub, <i8 5, i8 5>
424  call void @use.v2i8(<2 x i8> %sub)
425  ret <2 x i1> %cmp
426}
427
428declare i8 @llvm.usub.sat.i8(i8, i8)
429declare i16 @llvm.usub.sat.i16(i16, i16)
430declare i32 @llvm.usub.sat.i32(i32, i32)
431declare i64 @llvm.usub.sat.i64(i64, i64)
432
433declare <2 x i64> @llvm.usub.sat.v2i64(<2 x i64>, <2 x i64>)
434declare <2 x i32> @llvm.usub.sat.v2i32(<2 x i32>, <2 x i32>)
435declare <2 x i16> @llvm.usub.sat.v2i16(<2 x i16>, <2 x i16>)
436declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
437
438declare void @use.i8(i8)
439declare void @use.v2i8(<2 x i8>)
440