xref: /llvm-project/llvm/test/Transforms/InstCombine/select-select.ll (revision d4798498c4a30efb03eebb56415a69fa60107414)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3
4define float @foo1(float %a) {
5; CHECK-LABEL: @foo1(
6; CHECK-NEXT:    [[B:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
7; CHECK-NEXT:    [[C:%.*]] = select i1 [[B]], float [[A]], float 0.000000e+00
8; CHECK-NEXT:    [[D:%.*]] = fcmp olt float [[C]], 1.000000e+00
9; CHECK-NEXT:    [[F:%.*]] = select i1 [[D]], float [[C]], float 1.000000e+00
10; CHECK-NEXT:    ret float [[F]]
11;
12  %b = fcmp ogt float %a, 0.0
13  %c = select i1 %b, float %a, float 0.0
14  %d = fcmp olt float %c, 1.0
15  %f = select i1 %d, float %c, float 1.0
16  ret float %f
17}
18
19define float @foo2(float %a) {
20; CHECK-LABEL: @foo2(
21; CHECK-NEXT:    [[B:%.*]] = fcmp ule float [[A:%.*]], 0.000000e+00
22; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt float [[A]], 1.000000e+00
23; CHECK-NEXT:    [[E:%.*]] = select i1 [[TMP1]], float [[A]], float 1.000000e+00
24; CHECK-NEXT:    [[F:%.*]] = select i1 [[B]], float 0.000000e+00, float [[E]]
25; CHECK-NEXT:    ret float [[F]]
26;
27  %b = fcmp ogt float %a, 0.0
28  %c = select i1 %b, float %a, float 0.0
29  %d = fcmp olt float %c, 1.0
30  %e = select i1 %b, float %a, float 0.0
31  %f = select i1 %d, float %e, float 1.0
32  ret float %f
33}
34
35define <2 x i32> @foo3(<2 x i1> %vec_bool, i1 %bool, <2 x i32> %V) {
36; CHECK-LABEL: @foo3(
37; CHECK-NEXT:    [[SEL0:%.*]] = select <2 x i1> [[VEC_BOOL:%.*]], <2 x i32> zeroinitializer, <2 x i32> [[V:%.*]]
38; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[BOOL:%.*]], <2 x i32> [[SEL0]], <2 x i32> [[V]]
39; CHECK-NEXT:    ret <2 x i32> [[SEL1]]
40;
41  %sel0 = select <2 x i1> %vec_bool, <2 x i32> zeroinitializer, <2 x i32> %V
42  %sel1 = select i1 %bool, <2 x i32> %sel0, <2 x i32> %V
43  ret <2 x i32> %sel1
44}
45
46; Four variations of (select (select-shuffle)) with a common operand.
47
48define <4 x i8> @sel_shuf_commute0(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) {
49; CHECK-LABEL: @sel_shuf_commute0(
50; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[Y:%.*]], <4 x i8> [[X:%.*]]
51; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[X]], <4 x i8> [[SEL]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
52; CHECK-NEXT:    ret <4 x i8> [[R]]
53;
54  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
55  %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %x
56  ret <4 x i8> %r
57}
58
59; Weird types are ok.
60
61define <5 x i9> @sel_shuf_commute1(<5 x i9> %x, <5 x i9> %y, <5 x i1> %cmp) {
62; CHECK-LABEL: @sel_shuf_commute1(
63; CHECK-NEXT:    [[SEL:%.*]] = select <5 x i1> [[CMP:%.*]], <5 x i9> [[X:%.*]], <5 x i9> [[Y:%.*]]
64; CHECK-NEXT:    [[R:%.*]] = shufflevector <5 x i9> [[SEL]], <5 x i9> [[Y]], <5 x i32> <i32 0, i32 6, i32 2, i32 8, i32 9>
65; CHECK-NEXT:    ret <5 x i9> [[R]]
66;
67  %blend = shufflevector <5 x i9> %x, <5 x i9> %y, <5 x i32> <i32 0, i32 6, i32 2, i32 8, i32 9>
68  %r = select <5 x i1> %cmp, <5 x i9> %blend, <5 x i9> %y
69  ret <5 x i9> %r
70}
71
72define <4 x float> @sel_shuf_commute2(<4 x float> %x, <4 x float> %y, <4 x i1> %cmp) {
73; CHECK-LABEL: @sel_shuf_commute2(
74; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]
75; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[SEL]], <4 x i32> <i32 0, i32 1, i32 2, i32 7>
76; CHECK-NEXT:    ret <4 x float> [[R]]
77;
78  %blend = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
79  %r = select <4 x i1> %cmp, <4 x float> %x, <4 x float> %blend
80  ret <4 x float> %r
81}
82
83; Scalar condition is ok.
84
85define <4 x i8> @sel_shuf_commute3(<4 x i8> %x, <4 x i8> %y, i1 %cmp) {
86; CHECK-LABEL: @sel_shuf_commute3(
87; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP:%.*]], <4 x i8> [[Y:%.*]], <4 x i8> [[X:%.*]]
88; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[SEL]], <4 x i8> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 3>
89; CHECK-NEXT:    ret <4 x i8> [[R]]
90;
91  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
92  %r = select i1 %cmp, <4 x i8> %y, <4 x i8> %blend
93  ret <4 x i8> %r
94}
95
96declare void @use(<4 x i8>)
97
98; Negative test - extra use would require another instruction.
99
100define <4 x i8> @sel_shuf_use(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) {
101; CHECK-LABEL: @sel_shuf_use(
102; CHECK-NEXT:    [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
103; CHECK-NEXT:    call void @use(<4 x i8> [[BLEND]])
104; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[BLEND]], <4 x i8> [[X]]
105; CHECK-NEXT:    ret <4 x i8> [[R]]
106;
107  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
108  call void @use(<4 x i8> %blend)
109  %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %x
110  ret <4 x i8> %r
111}
112
113; Negative test - undef in shuffle mask prevents transform.
114
115define <4 x i8> @sel_shuf_undef(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) {
116; CHECK-LABEL: @sel_shuf_undef(
117; CHECK-NEXT:    [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 poison>
118; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[BLEND]], <4 x i8> [[Y]]
119; CHECK-NEXT:    ret <4 x i8> [[R]]
120;
121  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 undef>
122  %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %y
123  ret <4 x i8> %r
124}
125
126; Negative test - not a "select shuffle"
127
128define <4 x i8> @sel_shuf_not(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) {
129; CHECK-LABEL: @sel_shuf_not(
130; CHECK-NEXT:    [[NOTBLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 6>
131; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[NOTBLEND]], <4 x i8> [[Y]]
132; CHECK-NEXT:    ret <4 x i8> [[R]]
133;
134  %notblend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 6>
135  %r = select <4 x i1> %cmp, <4 x i8> %notblend, <4 x i8> %y
136  ret <4 x i8> %r
137}
138
139; Negative test - must shuffle one of the select operands
140
141define <4 x i8> @sel_shuf_no_common_operand(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp, <4 x i8> %z) {
142; CHECK-LABEL: @sel_shuf_no_common_operand(
143; CHECK-NEXT:    [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 3>
144; CHECK-NEXT:    [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[Z:%.*]], <4 x i8> [[BLEND]]
145; CHECK-NEXT:    ret <4 x i8> [[R]]
146;
147  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
148  %r = select <4 x i1> %cmp, <4 x i8> %z, <4 x i8> %blend
149  ret <4 x i8> %r
150}
151
152; Negative test - don't crash (this is not a select shuffle because it changes vector length)
153
154define <2 x i8> @sel_shuf_narrowing_commute1(<4 x i8> %x, <4 x i8> %y, <2 x i8> %x2, <2 x i1> %cmp) {
155; CHECK-LABEL: @sel_shuf_narrowing_commute1(
156; CHECK-NEXT:    [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 5>
157; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[BLEND]], <2 x i8> [[X2:%.*]]
158; CHECK-NEXT:    ret <2 x i8> [[R]]
159;
160  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <2 x i32> <i32 0, i32 5>
161  %r = select <2 x i1> %cmp, <2 x i8> %blend, <2 x i8> %x2
162  ret <2 x i8> %r
163}
164
165; Negative test - don't crash (this is not a select shuffle because it changes vector length)
166
167define <2 x i8> @sel_shuf_narrowing_commute2(<4 x i8> %x, <4 x i8> %y, <2 x i8> %x2, <2 x i1> %cmp) {
168; CHECK-LABEL: @sel_shuf_narrowing_commute2(
169; CHECK-NEXT:    [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 5>
170; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[X2:%.*]], <2 x i8> [[BLEND]]
171; CHECK-NEXT:    ret <2 x i8> [[R]]
172;
173  %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <2 x i32> <i32 0, i32 5>
174  %r = select <2 x i1> %cmp, <2 x i8> %x2, <2 x i8> %blend
175  ret <2 x i8> %r
176}
177
178define i8 @strong_order_cmp_slt_eq(i32 %a, i32 %b) {
179; CHECK-LABEL: @strong_order_cmp_slt_eq(
180; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
181; CHECK-NEXT:    ret i8 [[SEL_EQ]]
182;
183  %cmp.lt = icmp slt i32 %a, %b
184  %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
185  %cmp.eq = icmp eq i32 %a, %b
186  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
187  ret i8 %sel.eq
188}
189
190define i8 @strong_order_cmp_ult_eq(i32 %a, i32 %b) {
191; CHECK-LABEL: @strong_order_cmp_ult_eq(
192; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
193; CHECK-NEXT:    ret i8 [[SEL_EQ]]
194;
195  %cmp.lt = icmp ult i32 %a, %b
196  %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
197  %cmp.eq = icmp eq i32 %a, %b
198  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
199  ret i8 %sel.eq
200}
201
202define i8 @strong_order_cmp_slt_eq_wrong_const(i32 %a, i32 %b) {
203; CHECK-LABEL: @strong_order_cmp_slt_eq_wrong_const(
204; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
205; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -2, i8 1
206; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
207; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
208; CHECK-NEXT:    ret i8 [[SEL_EQ]]
209;
210  %cmp.lt = icmp slt i32 %a, %b
211  %sel.lt = select i1 %cmp.lt, i8 -2, i8 1
212  %cmp.eq = icmp eq i32 %a, %b
213  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
214  ret i8 %sel.eq
215}
216
217define i8 @strong_order_cmp_ult_eq_wrong_const(i32 %a, i32 %b) {
218; CHECK-LABEL: @strong_order_cmp_ult_eq_wrong_const(
219; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
220; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 3
221; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
222; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
223; CHECK-NEXT:    ret i8 [[SEL_EQ]]
224;
225  %cmp.lt = icmp ult i32 %a, %b
226  %sel.lt = select i1 %cmp.lt, i8 -1, i8 3
227  %cmp.eq = icmp eq i32 %a, %b
228  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
229  ret i8 %sel.eq
230}
231
232define i8 @strong_order_cmp_slt_ult_wrong_pred(i32 %a, i32 %b) {
233; CHECK-LABEL: @strong_order_cmp_slt_ult_wrong_pred(
234; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
235; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
236; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ult i32 [[A]], [[B]]
237; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
238; CHECK-NEXT:    ret i8 [[SEL_EQ]]
239;
240  %cmp.lt = icmp slt i32 %a, %b
241  %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
242  %cmp.eq = icmp ult i32 %a, %b
243  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
244  ret i8 %sel.eq
245}
246
247define i8 @strong_order_cmp_sgt_eq(i32 %a, i32 %b) {
248; CHECK-LABEL: @strong_order_cmp_sgt_eq(
249; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
250; CHECK-NEXT:    ret i8 [[SEL_EQ]]
251;
252  %cmp.gt = icmp sgt i32 %a, %b
253  %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
254  %cmp.eq = icmp eq i32 %a, %b
255  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
256  ret i8 %sel.eq
257}
258
259define i8 @strong_order_cmp_ugt_eq(i32 %a, i32 %b) {
260; CHECK-LABEL: @strong_order_cmp_ugt_eq(
261; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
262; CHECK-NEXT:    ret i8 [[SEL_EQ]]
263;
264  %cmp.gt = icmp ugt i32 %a, %b
265  %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
266  %cmp.eq = icmp eq i32 %a, %b
267  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
268  ret i8 %sel.eq
269}
270
271define i8 @strong_order_cmp_eq_slt(i32 %a, i32 %b) {
272; CHECK-LABEL: @strong_order_cmp_eq_slt(
273; CHECK-NEXT:    [[SEL_LT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
274; CHECK-NEXT:    ret i8 [[SEL_LT]]
275;
276  %cmp.eq = icmp eq i32 %a, %b
277  %sel.eq = select i1 %cmp.eq, i8 0, i8 1
278  %cmp.lt = icmp slt i32 %a, %b
279  %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq
280  ret i8 %sel.lt
281}
282
283define i8 @strong_order_cmp_eq_sgt(i32 %a, i32 %b) {
284; CHECK-LABEL: @strong_order_cmp_eq_sgt(
285; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
286; CHECK-NEXT:    ret i8 [[SEL_GT]]
287;
288  %cmp.eq = icmp eq i32 %a, %b
289  %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
290  %cmp.gt = icmp sgt i32 %a, %b
291  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
292  ret i8 %sel.gt
293}
294
295define i8 @strong_order_cmp_eq_ult(i32 %a, i32 %b) {
296; CHECK-LABEL: @strong_order_cmp_eq_ult(
297; CHECK-NEXT:    [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
298; CHECK-NEXT:    ret i8 [[SEL_LT]]
299;
300  %cmp.eq = icmp eq i32 %a, %b
301  %sel.eq = select i1 %cmp.eq, i8 0, i8 1
302  %cmp.lt = icmp ult i32 %a, %b
303  %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq
304  ret i8 %sel.lt
305}
306
307define i8 @strong_order_cmp_eq_ugt(i32 %a, i32 %b) {
308; CHECK-LABEL: @strong_order_cmp_eq_ugt(
309; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
310; CHECK-NEXT:    ret i8 [[SEL_GT]]
311;
312  %cmp.eq = icmp eq i32 %a, %b
313  %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
314  %cmp.gt = icmp ugt i32 %a, %b
315  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
316  ret i8 %sel.gt
317}
318
319define i8 @strong_order_cmp_slt_sgt(i32 %a, i32 %b) {
320; CHECK-LABEL: @strong_order_cmp_slt_sgt(
321; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
322; CHECK-NEXT:    ret i8 [[SEL_GT]]
323;
324  %cmp.lt = icmp slt i32 %a, %b
325  %sext = sext i1 %cmp.lt to i8
326  %cmp.gt = icmp sgt i32 %a, %b
327  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
328  ret i8 %sel.gt
329}
330
331define i8 @strong_order_cmp_ult_ugt(i32 %a, i32 %b) {
332; CHECK-LABEL: @strong_order_cmp_ult_ugt(
333; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
334; CHECK-NEXT:    ret i8 [[SEL_GT]]
335;
336  %cmp.lt = icmp ult i32 %a, %b
337  %sext = sext i1 %cmp.lt to i8
338  %cmp.gt = icmp ugt i32 %a, %b
339  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
340  ret i8 %sel.gt
341}
342
343define i8 @strong_order_cmp_sgt_slt(i32 %a, i32 %b) {
344; CHECK-LABEL: @strong_order_cmp_sgt_slt(
345; CHECK-NEXT:    [[SEL_LT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
346; CHECK-NEXT:    ret i8 [[SEL_LT]]
347;
348  %cmp.gt = icmp sgt i32 %a, %b
349  %zext = zext i1 %cmp.gt to i8
350  %cmp.lt = icmp slt i32 %a, %b
351  %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
352  ret i8 %sel.lt
353}
354
355define i8 @strong_order_cmp_ugt_ult(i32 %a, i32 %b) {
356; CHECK-LABEL: @strong_order_cmp_ugt_ult(
357; CHECK-NEXT:    [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
358; CHECK-NEXT:    ret i8 [[SEL_LT]]
359;
360  %cmp.gt = icmp ugt i32 %a, %b
361  %zext = zext i1 %cmp.gt to i8
362  %cmp.lt = icmp ult i32 %a, %b
363  %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
364  ret i8 %sel.lt
365}
366
367define i8 @strong_order_cmp_ne_ugt_ne_not_one_use(i32 %a, i32 %b) {
368; CHECK-LABEL: @strong_order_cmp_ne_ugt_ne_not_one_use(
369; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
370; CHECK-NEXT:    call void @use1(i1 [[CMP_NE]])
371; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
372; CHECK-NEXT:    ret i8 [[SEL_GT]]
373;
374  %cmp.ne = icmp ne i32 %a, %b
375  call void @use1(i1 %cmp.ne)
376  %sel.eq = sext i1 %cmp.ne to i8
377  %cmp.gt = icmp ugt i32 %a, %b
378  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
379  ret i8 %sel.gt
380}
381
382define i8 @strong_order_cmp_slt_eq_slt_not_oneuse(i32 %a, i32 %b) {
383; CHECK-LABEL: @strong_order_cmp_slt_eq_slt_not_oneuse(
384; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
385; CHECK-NEXT:    call void @use1(i1 [[CMP_LT]])
386; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
387; CHECK-NEXT:    ret i8 [[SEL_EQ]]
388;
389  %cmp.lt = icmp slt i32 %a, %b
390  call void @use1(i1 %cmp.lt)
391  %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
392  %cmp.eq = icmp eq i32 %a, %b
393  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
394  ret i8 %sel.eq
395}
396
397define i8 @strong_order_cmp_sgt_eq_eq_not_oneuse(i32 %a, i32 %b) {
398; CHECK-LABEL: @strong_order_cmp_sgt_eq_eq_not_oneuse(
399; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
400; CHECK-NEXT:    call void @use1(i1 [[CMP_EQ]])
401; CHECK-NEXT:    [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
402; CHECK-NEXT:    ret i8 [[SEL_EQ]]
403;
404  %cmp.gt = icmp sgt i32 %a, %b
405  %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
406  %cmp.eq = icmp eq i32 %a, %b
407  call void @use1(i1 %cmp.eq)
408  %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
409  ret i8 %sel.eq
410}
411
412define i8 @strong_order_cmp_eq_ugt_eq_not_oneuse(i32 %a, i32 %b) {
413; CHECK-LABEL: @strong_order_cmp_eq_ugt_eq_not_oneuse(
414; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
415; CHECK-NEXT:    call void @use1(i1 [[CMP_EQ]])
416; CHECK-NEXT:    [[NOT_CMP_EQ:%.*]] = xor i1 [[CMP_EQ]], true
417; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext i1 [[NOT_CMP_EQ]] to i8
418; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]]
419; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]]
420; CHECK-NEXT:    ret i8 [[SEL_GT]]
421;
422  %cmp.eq = icmp eq i32 %a, %b
423  call void @use1(i1 %cmp.eq)
424  %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
425  %cmp.gt = icmp ugt i32 %a, %b
426  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
427  ret i8 %sel.gt
428}
429
430define i8 @strong_order_cmp_ugt_ult_zext_not_oneuse(i32 %a, i32 %b) {
431; CHECK-LABEL: @strong_order_cmp_ugt_ult_zext_not_oneuse(
432; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
433; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP_GT]] to i8
434; CHECK-NEXT:    call void @use8(i8 [[ZEXT]])
435; CHECK-NEXT:    [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
436; CHECK-NEXT:    ret i8 [[SEL_LT]]
437;
438  %cmp.gt = icmp ugt i32 %a, %b
439  %zext = zext i1 %cmp.gt to i8
440  call void @use8(i8 %zext)
441  %cmp.lt = icmp ult i32 %a, %b
442  %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
443  ret i8 %sel.lt
444}
445
446define i8 @strong_order_cmp_slt_sgt_sext_not_oneuse(i32 %a, i32 %b) {
447; CHECK-LABEL: @strong_order_cmp_slt_sgt_sext_not_oneuse(
448; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
449; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[CMP_LT]] to i8
450; CHECK-NEXT:    call void @use8(i8 [[SEXT]])
451; CHECK-NEXT:    [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
452; CHECK-NEXT:    ret i8 [[SEL_GT]]
453;
454  %cmp.lt = icmp slt i32 %a, %b
455  %sext = sext i1 %cmp.lt to i8
456  call void @use8(i8 %sext)
457  %cmp.gt = icmp sgt i32 %a, %b
458  %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
459  ret i8 %sel.gt
460}
461
462define <2 x i8> @strong_order_cmp_ugt_ult_vector(<2 x i32> %a, <2 x i32> %b) {
463; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector(
464; CHECK-NEXT:    [[SEL_LT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
465; CHECK-NEXT:    ret <2 x i8> [[SEL_LT]]
466;
467  %cmp.gt = icmp ugt <2 x i32> %a, %b
468  %zext = zext <2 x i1> %cmp.gt to <2 x i8>
469  %cmp.lt = icmp ult <2 x i32> %a, %b
470  %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 -1, i8 -1>, <2 x i8> %zext
471  ret <2 x i8> %sel.lt
472}
473
474define <2 x i8> @strong_order_cmp_ugt_ult_vector_poison(<2 x i32> %a, <2 x i32> %b) {
475; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector_poison(
476; CHECK-NEXT:    [[SEL_LT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
477; CHECK-NEXT:    ret <2 x i8> [[SEL_LT]]
478;
479  %cmp.gt = icmp ugt <2 x i32> %a, %b
480  %zext = zext <2 x i1> %cmp.gt to <2 x i8>
481  %cmp.lt = icmp ult <2 x i32> %a, %b
482  %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 poison, i8 -1>, <2 x i8> %zext
483  ret <2 x i8> %sel.lt
484}
485
486define <2 x i8> @strong_order_cmp_eq_ugt_vector(<2 x i32> %a, <2 x i32> %b) {
487; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector(
488; CHECK-NEXT:    [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
489; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
490;
491  %cmp.eq = icmp eq <2 x i32> %a, %b
492  %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1>
493  %cmp.gt = icmp ugt <2 x i32> %a, %b
494  %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
495  ret <2 x i8> %sel.gt
496}
497
498define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison1(<2 x i32> %a, <2 x i32> %b) {
499; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison1(
500; CHECK-NEXT:    [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
501; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
502;
503  %cmp.eq = icmp eq <2 x i32> %a, %b
504  %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 poison>, <2 x i8> <i8 -1, i8 -1>
505  %cmp.gt = icmp ugt <2 x i32> %a, %b
506  %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
507  ret <2 x i8> %sel.gt
508}
509
510define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison2(<2 x i32> %a, <2 x i32> %b) {
511; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison2(
512; CHECK-NEXT:    [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
513; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
514;
515  %cmp.eq = icmp eq <2 x i32> %a, %b
516  %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 poison, i8 -1>
517  %cmp.gt = icmp ugt <2 x i32> %a, %b
518  %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
519  ret <2 x i8> %sel.gt
520}
521
522define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison3(<2 x i32> %a, <2 x i32> %b) {
523; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison3(
524; CHECK-NEXT:    [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]])
525; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
526;
527  %cmp.eq = icmp eq <2 x i32> %a, %b
528  %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1>
529  %cmp.gt = icmp ugt <2 x i32> %a, %b
530  %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 poison>, <2 x i8> %sel.eq
531  ret <2 x i8> %sel.gt
532}
533
534
535
536declare void @use1(i1)
537declare void @use8(i8)
538