xref: /llvm-project/llvm/test/Transforms/InstCombine/scmp.ll (revision d4798498c4a30efb03eebb56415a69fa60107414)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(i8 %value)
5
6define i1 @scmp_eq_0(i32 %x, i32 %y) {
7; CHECK-LABEL: define i1 @scmp_eq_0(
8; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
9; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]
10; CHECK-NEXT:    ret i1 [[TMP2]]
11;
12  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
13  %2 = icmp eq i8 %1, 0
14  ret i1 %2
15}
16
17define i1 @scmp_ne_0(i32 %x, i32 %y) {
18; CHECK-LABEL: define i1 @scmp_ne_0(
19; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
20; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]
21; CHECK-NEXT:    ret i1 [[TMP2]]
22;
23  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
24  %2 = icmp ne i8 %1, 0
25  ret i1 %2
26}
27
28define i1 @scmp_eq_1(i32 %x, i32 %y) {
29; CHECK-LABEL: define i1 @scmp_eq_1(
30; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
31; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
32; CHECK-NEXT:    ret i1 [[TMP2]]
33;
34  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
35  %2 = icmp eq i8 %1, 1
36  ret i1 %2
37}
38
39define i1 @scmp_ne_1(i32 %x, i32 %y) {
40; CHECK-LABEL: define i1 @scmp_ne_1(
41; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
43; CHECK-NEXT:    ret i1 [[TMP2]]
44;
45  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
46  %2 = icmp ne i8 %1, 1
47  ret i1 %2
48}
49
50define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {
51; CHECK-LABEL: define i1 @scmp_eq_negative_1(
52; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
53; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
54; CHECK-NEXT:    ret i1 [[TMP2]]
55;
56  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
57  %2 = icmp eq i8 %1, -1
58  ret i1 %2
59}
60
61define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {
62; CHECK-LABEL: define i1 @scmp_ne_negative_1(
63; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
64; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
65; CHECK-NEXT:    ret i1 [[TMP2]]
66;
67  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
68  %2 = icmp ne i8 %1, -1
69  ret i1 %2
70}
71
72define i1 @scmp_sgt_0(i32 %x, i32 %y) {
73; CHECK-LABEL: define i1 @scmp_sgt_0(
74; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
75; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
76; CHECK-NEXT:    ret i1 [[TMP2]]
77;
78  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
79  %2 = icmp sgt i8 %1, 0
80  ret i1 %2
81}
82
83define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {
84; CHECK-LABEL: define i1 @scmp_sgt_neg_1(
85; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
86; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
87; CHECK-NEXT:    ret i1 [[TMP2]]
88;
89  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
90  %2 = icmp sgt i8 %1, -1
91  ret i1 %2
92}
93
94define i1 @scmp_sge_0(i32 %x, i32 %y) {
95; CHECK-LABEL: define i1 @scmp_sge_0(
96; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
97; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
98; CHECK-NEXT:    ret i1 [[TMP2]]
99;
100  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
101  %2 = icmp sge i8 %1, 0
102  ret i1 %2
103}
104
105define i1 @scmp_sge_1(i32 %x, i32 %y) {
106; CHECK-LABEL: define i1 @scmp_sge_1(
107; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
108; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
109; CHECK-NEXT:    ret i1 [[TMP2]]
110;
111  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
112  %2 = icmp sge i8 %1, 1
113  ret i1 %2
114}
115
116define i1 @scmp_slt_0(i32 %x, i32 %y) {
117; CHECK-LABEL: define i1 @scmp_slt_0(
118; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
119; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
120; CHECK-NEXT:    ret i1 [[TMP2]]
121;
122  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
123  %2 = icmp slt i8 %1, 0
124  ret i1 %2
125}
126
127define i1 @scmp_slt_1(i32 %x, i32 %y) {
128; CHECK-LABEL: define i1 @scmp_slt_1(
129; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
130; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
131; CHECK-NEXT:    ret i1 [[TMP2]]
132;
133  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
134  %2 = icmp slt i8 %1, 1
135  ret i1 %2
136}
137
138define i1 @scmp_sle_0(i32 %x, i32 %y) {
139; CHECK-LABEL: define i1 @scmp_sle_0(
140; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
141; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
142; CHECK-NEXT:    ret i1 [[TMP2]]
143;
144  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
145  %2 = icmp sle i8 %1, 0
146  ret i1 %2
147}
148
149define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
150; CHECK-LABEL: define i1 @scmp_sle_neg_1(
151; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
152; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
153; CHECK-NEXT:    ret i1 [[TMP2]]
154;
155  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
156  %2 = icmp sle i8 %1, -1
157  ret i1 %2
158}
159
160; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1
161define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
162; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(
163; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
164; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]]
165; CHECK-NEXT:    ret i1 [[TMP1]]
166;
167  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
168  %2 = icmp ult i8 %1, 4
169  ret i1 %2
170}
171
172; scmp(x, y) s> C => x s< y when C != 0 and C != -1
173define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
174; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
175; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
176; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
177; CHECK-NEXT:    ret i1 [[TMP2]]
178;
179  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
180  %2 = icmp ugt i8 %1, 12
181  ret i1 %2
182}
183
184
185; ========== Fold -scmp(x, y) => scmp(y, x) ==========
186define i8 @scmp_negated(i32 %x, i32 %y) {
187; CHECK-LABEL: define i8 @scmp_negated(
188; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
189; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
190; CHECK-NEXT:    ret i8 [[TMP2]]
191;
192  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
193  %2 = sub i8 0, %1
194  ret i8 %2
195}
196
197; Negative test: do not fold if the original scmp result is already used
198define i8 @scmp_negated_multiuse(i32 %x, i32 %y) {
199; CHECK-LABEL: define i8 @scmp_negated_multiuse(
200; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
201; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
202; CHECK-NEXT:    call void @use(i8 [[TMP1]])
203; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[TMP1]]
204; CHECK-NEXT:    ret i8 [[TMP2]]
205;
206  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
207  call void @use(i8 %1)
208  %2 = sub i8 0, %1
209  ret i8 %2
210}
211
212; Fold ((x s< y) ? -1 : (x != y)) into scmp(x, y)
213define i8 @scmp_from_select_lt(i32 %x, i32 %y) {
214; CHECK-LABEL: define i8 @scmp_from_select_lt(
215; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
216; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
217; CHECK-NEXT:    ret i8 [[R]]
218;
219  %ne_bool = icmp ne i32 %x, %y
220  %ne = zext i1 %ne_bool to i8
221  %lt = icmp slt i32 %x, %y
222  %r = select i1 %lt, i8 -1, i8 %ne
223  ret i8 %r
224}
225
226; Fold (x s< y) ? -1 : zext(x s> y) into scmp(x, y)
227define i8 @scmp_from_select_lt_and_gt(i32 %x, i32 %y) {
228; CHECK-LABEL: define i8 @scmp_from_select_lt_and_gt(
229; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
230; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
231; CHECK-NEXT:    ret i8 [[R]]
232;
233  %gt_bool = icmp sgt i32 %x, %y
234  %gt = zext i1 %gt_bool to i8
235  %lt = icmp slt i32 %x, %y
236  %r = select i1 %lt, i8 -1, i8 %gt
237  ret i8 %r
238}
239
240; Vector version
241define <4 x i8> @scmp_from_select_vec_lt(<4 x i32> %x, <4 x i32> %y) {
242; CHECK-LABEL: define <4 x i8> @scmp_from_select_vec_lt(
243; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
244; CHECK-NEXT:    [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
245; CHECK-NEXT:    ret <4 x i8> [[R]]
246;
247  %ne_bool = icmp ne <4 x i32> %x, %y
248  %ne = zext <4 x i1> %ne_bool to <4 x i8>
249  %lt = icmp slt <4 x i32> %x, %y
250  %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne
251  ret <4 x i8> %r
252}
253
254; Fold (x s<= y) ? sext(x != y) : 1 into scmp(x, y)
255define i8 @scmp_from_select_le(i32 %x, i32 %y) {
256; CHECK-LABEL: define i8 @scmp_from_select_le(
257; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
258; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
259; CHECK-NEXT:    ret i8 [[R]]
260;
261  %ne_bool = icmp ne i32 %x, %y
262  %ne = sext i1 %ne_bool to i8
263  %le = icmp sle i32 %x, %y
264  %r = select i1 %le, i8 %ne, i8 1
265  ret i8 %r
266}
267
268; Fold (x s>= y) ? zext(x != y) : -1 into scmp(x, y)
269define i8 @scmp_from_select_ge(i32 %x, i32 %y) {
270; CHECK-LABEL: define i8 @scmp_from_select_ge(
271; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
272; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
273; CHECK-NEXT:    ret i8 [[R]]
274;
275  %ne_bool = icmp ne i32 %x, %y
276  %ne = zext i1 %ne_bool to i8
277  %ge = icmp sge i32 %x, %y
278  %r = select i1 %ge, i8 %ne, i8 -1
279  ret i8 %r
280}
281
282; Fold scmp(x nsw- y, 0) to scmp(x, y)
283define i8 @scmp_of_sub_and_zero(i32 %x, i32 %y) {
284; CHECK-LABEL: define i8 @scmp_of_sub_and_zero(
285; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
286; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
287; CHECK-NEXT:    ret i8 [[R]]
288;
289  %diff = sub nsw i32 %x, %y
290  %r = call i8 @llvm.scmp(i32 %diff, i32 0)
291  ret i8 %r
292}
293
294; Negative test: no nsw
295define i8 @scmp_of_sub_and_zero_neg_1(i32 %x, i32 %y) {
296; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg_1(
297; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
298; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[X]], [[Y]]
299; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 0)
300; CHECK-NEXT:    ret i8 [[R]]
301;
302  %diff = sub i32 %x, %y
303  %r = call i8 @llvm.scmp(i32 %diff, i32 0)
304  ret i8 %r
305}
306
307; Negative test: second argument of scmp is not 0
308define i8 @scmp_of_sub_and_zero_neg2(i32 %x, i32 %y) {
309; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg2(
310; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
311; CHECK-NEXT:    [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]
312; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 15)
313; CHECK-NEXT:    ret i8 [[R]]
314;
315  %diff = sub nsw i32 %x, %y
316  %r = call i8 @llvm.scmp(i32 %diff, i32 15)
317  ret i8 %r
318}
319
320; Negative test: calling ucmp instead of scmp
321define i8 @scmp_of_sub_and_zero_neg3(i32 %x, i32 %y) {
322; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg3(
323; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
324; CHECK-NEXT:    [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]
325; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[DIFF]], i32 0)
326; CHECK-NEXT:    ret i8 [[R]]
327;
328  %diff = sub nsw i32 %x, %y
329  %r = call i8 @llvm.ucmp(i32 %diff, i32 0)
330  ret i8 %r
331}
332
333; Fold (x s> y) ? 1 : sext(x s< y)
334define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
335; CHECK-LABEL: define i8 @scmp_from_select_gt_and_lt(
336; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
337; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
338; CHECK-NEXT:    ret i8 [[R]]
339;
340  %lt_bool = icmp slt i32 %x, %y
341  %lt = sext i1 %lt_bool to i8
342  %gt = icmp sgt i32 %x, %y
343  %r = select i1 %gt, i8 1, i8 %lt
344  ret i8 %r
345}
346
347; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)
348define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
349; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
352; CHECK-NEXT:    ret i8 [[R]]
353;
354  %eq = icmp eq i32 %x, %y
355  %gt = icmp sgt i32 %x, %y
356  %sel1 = select i1 %gt, i8 1, i8 -1
357  %r = select i1 %eq, i8 0, i8 %sel1
358  ret i8 %r
359}
360
361define i8 @scmp_from_select_eq_and_gt_inverse(i32 %x, i32 %y) {
362; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(
363; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
364; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
365; CHECK-NEXT:    ret i8 [[R]]
366;
367  %ne = icmp ne i32 %x, %y
368  %gt = icmp sgt i32 %x, %y
369  %sel1 = select i1 %gt, i8 1, i8 -1
370  %r = select i1 %ne, i8 %sel1, i8 0
371  ret i8 %r
372}
373
374define <4 x i8> @scmp_from_select_eq_and_gt_vec(<4 x i32> %x, <4 x i32> %y) {
375; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(
376; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
377; CHECK-NEXT:    [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
378; CHECK-NEXT:    ret <4 x i8> [[R]]
379;
380  %eq = icmp eq <4 x i32> %x, %y
381  %gt = icmp sgt <4 x i32> %x, %y
382  %sel1 = select <4 x i1> %gt, <4 x i8> splat(i8 1), <4 x i8> splat(i8 -1)
383  %r = select <4 x i1> %eq, <4 x i8> splat(i8 0), <4 x i8> %sel1
384  ret <4 x i8> %r
385}
386
387define i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {
388; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
389; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
390; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
391; CHECK-NEXT:    ret i8 [[R]]
392;
393  %eq = icmp eq i32 %x, %y
394  %gt = icmp slt i32 %x, %y
395  %sel1 = select i1 %gt, i8 1, i8 -1
396  %r = select i1 %eq, i8 0, i8 %sel1
397  ret i8 %r
398}
399
400define i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {
401; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
402; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
403; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
404; CHECK-NEXT:    ret i8 [[R]]
405;
406  %eq = icmp eq i32 %x, %y
407  %gt = icmp sgt i32 %x, %y
408  %sel1 = select i1 %gt, i8 -1, i8 1
409  %r = select i1 %eq, i8 0, i8 %sel1
410  ret i8 %r
411}
412
413define i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {
414; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
415; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
416; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
417; CHECK-NEXT:    ret i8 [[R]]
418;
419  %eq = icmp eq i32 %x, %y
420  %gt = icmp slt i32 %x, %y
421  %sel1 = select i1 %gt, i8 -1, i8 1
422  %r = select i1 %eq, i8 0, i8 %sel1
423  ret i8 %r
424}
425
426; Negative test: true value of outer select is not zero
427define i8 @scmp_from_select_eq_and_gt_neg1(i32 %x, i32 %y) {
428; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
429; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
431; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
432; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
433; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]
434; CHECK-NEXT:    ret i8 [[R]]
435;
436  %eq = icmp eq i32 %x, %y
437  %gt = icmp sgt i32 %x, %y
438  %sel1 = select i1 %gt, i8 1, i8 -1
439  %r = select i1 %eq, i8 5, i8 %sel1
440  ret i8 %r
441}
442
443; Negative test: true value of inner select is not 1 or -1
444define i8 @scmp_from_select_eq_and_gt_neg2(i32 %x, i32 %y) {
445; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(
446; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
447; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
448; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
449; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1
450; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
451; CHECK-NEXT:    ret i8 [[R]]
452;
453  %eq = icmp eq i32 %x, %y
454  %gt = icmp sgt i32 %x, %y
455  %sel1 = select i1 %gt, i8 2, i8 -1
456  %r = select i1 %eq, i8 0, i8 %sel1
457  ret i8 %r
458}
459
460; Negative test: false value of inner select is not 1 or -1
461define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
462; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(
463; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
464; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
465; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
466; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22
467; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
468; CHECK-NEXT:    ret i8 [[R]]
469;
470  %eq = icmp eq i32 %x, %y
471  %gt = icmp sgt i32 %x, %y
472  %sel1 = select i1 %gt, i8 1, i8 22
473  %r = select i1 %eq, i8 0, i8 %sel1
474  ret i8 %r
475}
476