Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / select-select.ll
blob84fe973093e327f0bb586c40fd07a1d6ea580adf
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 define 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]]
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
19 define float @foo2(float %a) {
20 ; CHECK-LABEL: @foo2(
21 ; CHECK-NEXT:    [[B:%.*]] = fcmp ule float [[C:%.*]], 0.000000e+00
22 ; CHECK-NEXT:    [[D:%.*]] = fcmp olt float [[C]], 1.000000e+00
23 ; CHECK-NEXT:    [[E:%.*]] = select i1 [[D]], float [[C]], float 1.000000e+00
24 ; CHECK-NEXT:    [[F:%.*]] = select i1 [[B]], float 0.000000e+00, float [[E]]
25 ; CHECK-NEXT:    ret float [[F]]
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
35 define <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]]
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
46 ; Four variations of (select (select-shuffle)) with a common operand.
48 define <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]]
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
59 ; Weird types are ok.
61 define <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]]
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
72 define <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]]
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
83 ; Scalar condition is ok.
85 define <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]]
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
96 declare void @use(<4 x i8>)
98 ; Negative test - extra use would require another instruction.
100 define <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]]
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
113 ; Negative test - undef in shuffle mask prevents transform.
115 define <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]]
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
126 ; Negative test - not a "select shuffle"
128 define <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]]
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
139 ; Negative test - must shuffle one of the select operands
141 define <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]]
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
152 ; Negative test - don't crash (this is not a select shuffle because it changes vector length)
154 define <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]]
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
165 ; Negative test - don't crash (this is not a select shuffle because it changes vector length)
167 define <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]]
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
178 define i8 @strong_order_cmp_slt_eq(i32 %a, i32 %b) {
179 ; CHECK-LABEL: @strong_order_cmp_slt_eq(
180 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
181 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
182 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
183 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
184 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
186   %cmp.lt = icmp slt i32 %a, %b
187   %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
188   %cmp.eq = icmp eq i32 %a, %b
189   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
190   ret i8 %sel.eq
193 define i8 @strong_order_cmp_ult_eq(i32 %a, i32 %b) {
194 ; CHECK-LABEL: @strong_order_cmp_ult_eq(
195 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
196 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
197 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
198 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
199 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
201   %cmp.lt = icmp ult i32 %a, %b
202   %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
203   %cmp.eq = icmp eq i32 %a, %b
204   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
205   ret i8 %sel.eq
208 define i8 @strong_order_cmp_slt_eq_wrong_const(i32 %a, i32 %b) {
209 ; CHECK-LABEL: @strong_order_cmp_slt_eq_wrong_const(
210 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
211 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -2, i8 1
212 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
213 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
214 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
216   %cmp.lt = icmp slt i32 %a, %b
217   %sel.lt = select i1 %cmp.lt, i8 -2, i8 1
218   %cmp.eq = icmp eq i32 %a, %b
219   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
220   ret i8 %sel.eq
223 define i8 @strong_order_cmp_ult_eq_wrong_const(i32 %a, i32 %b) {
224 ; CHECK-LABEL: @strong_order_cmp_ult_eq_wrong_const(
225 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
226 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 3
227 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
228 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
229 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
231   %cmp.lt = icmp ult i32 %a, %b
232   %sel.lt = select i1 %cmp.lt, i8 -1, i8 3
233   %cmp.eq = icmp eq i32 %a, %b
234   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
235   ret i8 %sel.eq
238 define i8 @strong_order_cmp_slt_ult_wrong_pred(i32 %a, i32 %b) {
239 ; CHECK-LABEL: @strong_order_cmp_slt_ult_wrong_pred(
240 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
241 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
242 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ult i32 [[A]], [[B]]
243 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
244 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
246   %cmp.lt = icmp slt i32 %a, %b
247   %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
248   %cmp.eq = icmp ult i32 %a, %b
249   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
250   ret i8 %sel.eq
253 define i8 @strong_order_cmp_sgt_eq(i32 %a, i32 %b) {
254 ; CHECK-LABEL: @strong_order_cmp_sgt_eq(
255 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
256 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
257 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
258 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
259 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
261   %cmp.gt = icmp sgt i32 %a, %b
262   %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
263   %cmp.eq = icmp eq i32 %a, %b
264   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
265   ret i8 %sel.eq
268 define i8 @strong_order_cmp_ugt_eq(i32 %a, i32 %b) {
269 ; CHECK-LABEL: @strong_order_cmp_ugt_eq(
270 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
271 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
272 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
273 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
274 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
276   %cmp.gt = icmp ugt i32 %a, %b
277   %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
278   %cmp.eq = icmp eq i32 %a, %b
279   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
280   ret i8 %sel.eq
283 define i8 @strong_order_cmp_eq_slt(i32 %a, i32 %b) {
284 ; CHECK-LABEL: @strong_order_cmp_eq_slt(
285 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
286 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = zext i1 [[CMP_EQ]] to i8
287 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A]], [[B]]
288 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[SEL_EQ]]
289 ; CHECK-NEXT:    ret i8 [[SEL_LT]]
291   %cmp.eq = icmp eq i32 %a, %b
292   %sel.eq = select i1 %cmp.eq, i8 0, i8 1
293   %cmp.lt = icmp slt i32 %a, %b
294   %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq
295   ret i8 %sel.lt
298 define i8 @strong_order_cmp_eq_sgt(i32 %a, i32 %b) {
299 ; CHECK-LABEL: @strong_order_cmp_eq_sgt(
300 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
301 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext i1 [[CMP_EQ]] to i8
302 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A]], [[B]]
303 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]]
304 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
306   %cmp.eq = icmp eq i32 %a, %b
307   %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
308   %cmp.gt = icmp sgt i32 %a, %b
309   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
310   ret i8 %sel.gt
313 define i8 @strong_order_cmp_eq_ult(i32 %a, i32 %b) {
314 ; CHECK-LABEL: @strong_order_cmp_eq_ult(
315 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
316 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = zext i1 [[CMP_EQ]] to i8
317 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A]], [[B]]
318 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[SEL_EQ]]
319 ; CHECK-NEXT:    ret i8 [[SEL_LT]]
321   %cmp.eq = icmp eq i32 %a, %b
322   %sel.eq = select i1 %cmp.eq, i8 0, i8 1
323   %cmp.lt = icmp ult i32 %a, %b
324   %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq
325   ret i8 %sel.lt
328 define i8 @strong_order_cmp_eq_ugt(i32 %a, i32 %b) {
329 ; CHECK-LABEL: @strong_order_cmp_eq_ugt(
330 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
331 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext i1 [[CMP_EQ]] to i8
332 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]]
333 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]]
334 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
336   %cmp.eq = icmp eq i32 %a, %b
337   %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
338   %cmp.gt = icmp ugt i32 %a, %b
339   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
340   ret i8 %sel.gt
343 define i8 @strong_order_cmp_slt_sgt(i32 %a, i32 %b) {
344 ; CHECK-LABEL: @strong_order_cmp_slt_sgt(
345 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
346 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[CMP_LT]] to i8
347 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A]], [[B]]
348 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEXT]]
349 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
351   %cmp.lt = icmp slt i32 %a, %b
352   %sext = sext i1 %cmp.lt to i8
353   %cmp.gt = icmp sgt i32 %a, %b
354   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
355   ret i8 %sel.gt
358 define i8 @strong_order_cmp_ult_ugt(i32 %a, i32 %b) {
359 ; CHECK-LABEL: @strong_order_cmp_ult_ugt(
360 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
361 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[CMP_LT]] to i8
362 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]]
363 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEXT]]
364 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
366   %cmp.lt = icmp ult i32 %a, %b
367   %sext = sext i1 %cmp.lt to i8
368   %cmp.gt = icmp ugt i32 %a, %b
369   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
370   ret i8 %sel.gt
373 define i8 @strong_order_cmp_sgt_slt(i32 %a, i32 %b) {
374 ; CHECK-LABEL: @strong_order_cmp_sgt_slt(
375 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
376 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP_GT]] to i8
377 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A]], [[B]]
378 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[ZEXT]]
379 ; CHECK-NEXT:    ret i8 [[SEL_LT]]
381   %cmp.gt = icmp sgt i32 %a, %b
382   %zext = zext i1 %cmp.gt to i8
383   %cmp.lt = icmp slt i32 %a, %b
384   %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
385   ret i8 %sel.lt
388 define i8 @strong_order_cmp_ugt_ult(i32 %a, i32 %b) {
389 ; CHECK-LABEL: @strong_order_cmp_ugt_ult(
390 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
391 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP_GT]] to i8
392 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A]], [[B]]
393 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[ZEXT]]
394 ; CHECK-NEXT:    ret i8 [[SEL_LT]]
396   %cmp.gt = icmp ugt i32 %a, %b
397   %zext = zext i1 %cmp.gt to i8
398   %cmp.lt = icmp ult i32 %a, %b
399   %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
400   ret i8 %sel.lt
403 define i8 @strong_order_cmp_ne_ugt_ne_not_one_use(i32 %a, i32 %b) {
404 ; CHECK-LABEL: @strong_order_cmp_ne_ugt_ne_not_one_use(
405 ; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
406 ; CHECK-NEXT:    call void @use1(i1 [[CMP_NE]])
407 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext i1 [[CMP_NE]] to i8
408 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]]
409 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]]
410 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
412   %cmp.ne = icmp ne i32 %a, %b
413   call void @use1(i1 %cmp.ne)
414   %sel.eq = sext i1 %cmp.ne to i8
415   %cmp.gt = icmp ugt i32 %a, %b
416   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
417   ret i8 %sel.gt
420 define i8 @strong_order_cmp_slt_eq_slt_not_oneuse(i32 %a, i32 %b) {
421 ; CHECK-LABEL: @strong_order_cmp_slt_eq_slt_not_oneuse(
422 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
423 ; CHECK-NEXT:    call void @use1(i1 [[CMP_LT]])
424 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
425 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
426 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
427 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
429   %cmp.lt = icmp slt i32 %a, %b
430   call void @use1(i1 %cmp.lt)
431   %sel.lt = select i1 %cmp.lt, i8 -1, i8 1
432   %cmp.eq = icmp eq i32 %a, %b
433   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt
434   ret i8 %sel.eq
437 define i8 @strong_order_cmp_sgt_eq_eq_not_oneuse(i32 %a, i32 %b) {
438 ; CHECK-LABEL: @strong_order_cmp_sgt_eq_eq_not_oneuse(
439 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
440 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
441 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
442 ; CHECK-NEXT:    call void @use1(i1 [[CMP_EQ]])
443 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
444 ; CHECK-NEXT:    ret i8 [[SEL_EQ]]
446   %cmp.gt = icmp sgt i32 %a, %b
447   %sel.gt = select i1 %cmp.gt, i8 1, i8 -1
448   %cmp.eq = icmp eq i32 %a, %b
449   call void @use1(i1 %cmp.eq)
450   %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt
451   ret i8 %sel.eq
454 define i8 @strong_order_cmp_eq_ugt_eq_not_oneuse(i32 %a, i32 %b) {
455 ; CHECK-LABEL: @strong_order_cmp_eq_ugt_eq_not_oneuse(
456 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
457 ; CHECK-NEXT:    call void @use1(i1 [[CMP_EQ]])
458 ; CHECK-NEXT:    [[NOT_CMP_EQ:%.*]] = xor i1 [[CMP_EQ]], true
459 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext i1 [[NOT_CMP_EQ]] to i8
460 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]]
461 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]]
462 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
464   %cmp.eq = icmp eq i32 %a, %b
465   call void @use1(i1 %cmp.eq)
466   %sel.eq = select i1 %cmp.eq, i8 0, i8 -1
467   %cmp.gt = icmp ugt i32 %a, %b
468   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq
469   ret i8 %sel.gt
472 define i8 @strong_order_cmp_ugt_ult_zext_not_oneuse(i32 %a, i32 %b) {
473 ; CHECK-LABEL: @strong_order_cmp_ugt_ult_zext_not_oneuse(
474 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
475 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP_GT]] to i8
476 ; CHECK-NEXT:    call void @use8(i8 [[ZEXT]])
477 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult i32 [[A]], [[B]]
478 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[ZEXT]]
479 ; CHECK-NEXT:    ret i8 [[SEL_LT]]
481   %cmp.gt = icmp ugt i32 %a, %b
482   %zext = zext i1 %cmp.gt to i8
483   call void @use8(i8 %zext)
484   %cmp.lt = icmp ult i32 %a, %b
485   %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext
486   ret i8 %sel.lt
489 define i8 @strong_order_cmp_slt_sgt_sext_not_oneuse(i32 %a, i32 %b) {
490 ; CHECK-LABEL: @strong_order_cmp_slt_sgt_sext_not_oneuse(
491 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
492 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[CMP_LT]] to i8
493 ; CHECK-NEXT:    call void @use8(i8 [[SEXT]])
494 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp sgt i32 [[A]], [[B]]
495 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEXT]]
496 ; CHECK-NEXT:    ret i8 [[SEL_GT]]
498   %cmp.lt = icmp slt i32 %a, %b
499   %sext = sext i1 %cmp.lt to i8
500   call void @use8(i8 %sext)
501   %cmp.gt = icmp sgt i32 %a, %b
502   %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext
503   ret i8 %sel.gt
506 define <2 x i8> @strong_order_cmp_ugt_ult_vector(<2 x i32> %a, <2 x i32> %b) {
507 ; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector(
508 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A:%.*]], [[B:%.*]]
509 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i1> [[CMP_GT]] to <2 x i8>
510 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult <2 x i32> [[A]], [[B]]
511 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select <2 x i1> [[CMP_LT]], <2 x i8> <i8 -1, i8 -1>, <2 x i8> [[ZEXT]]
512 ; CHECK-NEXT:    ret <2 x i8> [[SEL_LT]]
514   %cmp.gt = icmp ugt <2 x i32> %a, %b
515   %zext = zext <2 x i1> %cmp.gt to <2 x i8>
516   %cmp.lt = icmp ult <2 x i32> %a, %b
517   %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 -1, i8 -1>, <2 x i8> %zext
518   ret <2 x i8> %sel.lt
521 define <2 x i8> @strong_order_cmp_ugt_ult_vector_poison(<2 x i32> %a, <2 x i32> %b) {
522 ; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector_poison(
523 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A:%.*]], [[B:%.*]]
524 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i1> [[CMP_GT]] to <2 x i8>
525 ; CHECK-NEXT:    [[CMP_LT:%.*]] = icmp ult <2 x i32> [[A]], [[B]]
526 ; CHECK-NEXT:    [[SEL_LT:%.*]] = select <2 x i1> [[CMP_LT]], <2 x i8> <i8 poison, i8 -1>, <2 x i8> [[ZEXT]]
527 ; CHECK-NEXT:    ret <2 x i8> [[SEL_LT]]
529   %cmp.gt = icmp ugt <2 x i32> %a, %b
530   %zext = zext <2 x i1> %cmp.gt to <2 x i8>
531   %cmp.lt = icmp ult <2 x i32> %a, %b
532   %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 poison, i8 -1>, <2 x i8> %zext
533   ret <2 x i8> %sel.lt
536 define <2 x i8> @strong_order_cmp_eq_ugt_vector(<2 x i32> %a, <2 x i32> %b) {
537 ; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector(
538 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne <2 x i32> [[A:%.*]], [[B:%.*]]
539 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext <2 x i1> [[CMP_EQ]] to <2 x i8>
540 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A]], [[B]]
541 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select <2 x i1> [[CMP_GT]], <2 x i8> <i8 1, i8 1>, <2 x i8> [[SEL_EQ]]
542 ; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
544   %cmp.eq = icmp eq <2 x i32> %a, %b
545   %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1>
546   %cmp.gt = icmp ugt <2 x i32> %a, %b
547   %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
548   ret <2 x i8> %sel.gt
551 define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison1(<2 x i32> %a, <2 x i32> %b) {
552 ; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison1(
553 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne <2 x i32> [[A:%.*]], [[B:%.*]]
554 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext <2 x i1> [[CMP_EQ]] to <2 x i8>
555 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A]], [[B]]
556 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select <2 x i1> [[CMP_GT]], <2 x i8> <i8 1, i8 1>, <2 x i8> [[SEL_EQ]]
557 ; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
559   %cmp.eq = icmp eq <2 x i32> %a, %b
560   %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 poison>, <2 x i8> <i8 -1, i8 -1>
561   %cmp.gt = icmp ugt <2 x i32> %a, %b
562   %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
563   ret <2 x i8> %sel.gt
566 define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison2(<2 x i32> %a, <2 x i32> %b) {
567 ; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison2(
568 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne <2 x i32> [[A:%.*]], [[B:%.*]]
569 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext <2 x i1> [[CMP_EQ]] to <2 x i8>
570 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A]], [[B]]
571 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select <2 x i1> [[CMP_GT]], <2 x i8> <i8 1, i8 1>, <2 x i8> [[SEL_EQ]]
572 ; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
574   %cmp.eq = icmp eq <2 x i32> %a, %b
575   %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 poison, i8 -1>
576   %cmp.gt = icmp ugt <2 x i32> %a, %b
577   %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq
578   ret <2 x i8> %sel.gt
581 define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison3(<2 x i32> %a, <2 x i32> %b) {
582 ; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison3(
583 ; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp ne <2 x i32> [[A:%.*]], [[B:%.*]]
584 ; CHECK-NEXT:    [[SEL_EQ:%.*]] = sext <2 x i1> [[CMP_EQ]] to <2 x i8>
585 ; CHECK-NEXT:    [[CMP_GT:%.*]] = icmp ugt <2 x i32> [[A]], [[B]]
586 ; CHECK-NEXT:    [[SEL_GT:%.*]] = select <2 x i1> [[CMP_GT]], <2 x i8> <i8 1, i8 poison>, <2 x i8> [[SEL_EQ]]
587 ; CHECK-NEXT:    ret <2 x i8> [[SEL_GT]]
589   %cmp.eq = icmp eq <2 x i32> %a, %b
590   %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1>
591   %cmp.gt = icmp ugt <2 x i32> %a, %b
592   %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 poison>, <2 x i8> %sel.eq
593   ret <2 x i8> %sel.gt
598 declare void @use1(i1)
599 declare void @use8(i8)