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) {
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
19 define float @foo2(float %a) {
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
35 define <2 x i32> @foo3(<2 x i1> %vec_bool, i1 %bool, <2 x i32> %V) {
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
598 declare void @use1(i1)
599 declare void @use8(i8)