1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define i1 @f(i1 %cond, i32 %x, i32 %x2) {
6 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[X2:%.*]]
7 ; CHECK-NEXT: ret i1 [[C]]
9 %y = select i1 %cond, i32 poison, i32 %x
10 %c = icmp eq i32 %y, %x2
14 define i1 @icmp_ne_common_op00(i1 %c, i6 %x, i6 %y, i6 %z) {
15 ; CHECK-LABEL: @icmp_ne_common_op00(
16 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
17 ; CHECK-NEXT: [[R:%.*]] = icmp ne i6 [[X:%.*]], [[R_V]]
18 ; CHECK-NEXT: ret i1 [[R]]
20 %cmp1 = icmp ne i6 %x, %y
21 %cmp2 = icmp ne i6 %x, %z
22 %r = select i1 %c, i1 %cmp1, i1 %cmp2
26 define i1 @icmp_ne_common_op01(i1 %c, i3 %x, i3 %y, i3 %z) {
27 ; CHECK-LABEL: @icmp_ne_common_op01(
28 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i3 [[Y:%.*]], i3 [[Z:%.*]]
29 ; CHECK-NEXT: [[R:%.*]] = icmp ne i3 [[X:%.*]], [[R_V]]
30 ; CHECK-NEXT: ret i1 [[R]]
32 %cmp1 = icmp ne i3 %x, %y
33 %cmp2 = icmp ne i3 %z, %x
34 %r = select i1 %c, i1 %cmp1, i1 %cmp2
38 define i1 @icmp_ne_common_op10(i1 %c, i4 %x, i4 %y, i4 %z) {
39 ; CHECK-LABEL: @icmp_ne_common_op10(
40 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]
41 ; CHECK-NEXT: [[R:%.*]] = icmp ne i4 [[X:%.*]], [[R_V]]
42 ; CHECK-NEXT: ret i1 [[R]]
44 %cmp1 = icmp ne i4 %y, %x
45 %cmp2 = icmp ne i4 %x, %z
46 %r = select i1 %c, i1 %cmp1, i1 %cmp2
50 define <3 x i1> @icmp_ne_common_op11(<3 x i1> %c, <3 x i17> %x, <3 x i17> %y, <3 x i17> %z) {
51 ; CHECK-LABEL: @icmp_ne_common_op11(
52 ; CHECK-NEXT: [[R_V:%.*]] = select <3 x i1> [[C:%.*]], <3 x i17> [[Y:%.*]], <3 x i17> [[Z:%.*]]
53 ; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i17> [[X:%.*]], [[R_V]]
54 ; CHECK-NEXT: ret <3 x i1> [[R]]
56 %cmp1 = icmp ne <3 x i17> %y, %x
57 %cmp2 = icmp ne <3 x i17> %z, %x
58 %r = select <3 x i1> %c, <3 x i1> %cmp1, <3 x i1> %cmp2
62 define i1 @icmp_eq_common_op00(i1 %c, i5 %x, i5 %y, i5 %z) {
63 ; CHECK-LABEL: @icmp_eq_common_op00(
64 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i5 [[Y:%.*]], i5 [[Z:%.*]]
65 ; CHECK-NEXT: [[R:%.*]] = icmp eq i5 [[X:%.*]], [[R_V]]
66 ; CHECK-NEXT: ret i1 [[R]]
68 %cmp1 = icmp eq i5 %x, %y
69 %cmp2 = icmp eq i5 %x, %z
70 %r = select i1 %c, i1 %cmp1, i1 %cmp2
74 define <5 x i1> @icmp_eq_common_op01(<5 x i1> %c, <5 x i7> %x, <5 x i7> %y, <5 x i7> %z) {
75 ; CHECK-LABEL: @icmp_eq_common_op01(
76 ; CHECK-NEXT: [[R_V:%.*]] = select <5 x i1> [[C:%.*]], <5 x i7> [[Y:%.*]], <5 x i7> [[Z:%.*]]
77 ; CHECK-NEXT: [[R:%.*]] = icmp eq <5 x i7> [[X:%.*]], [[R_V]]
78 ; CHECK-NEXT: ret <5 x i1> [[R]]
80 %cmp1 = icmp eq <5 x i7> %x, %y
81 %cmp2 = icmp eq <5 x i7> %z, %x
82 %r = select <5 x i1> %c, <5 x i1> %cmp1, <5 x i1> %cmp2
86 define i1 @icmp_eq_common_op10(i1 %c, i32 %x, i32 %y, i32 %z) {
87 ; CHECK-LABEL: @icmp_eq_common_op10(
88 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]
89 ; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], [[R_V]]
90 ; CHECK-NEXT: ret i1 [[R]]
92 %cmp1 = icmp eq i32 %y, %x
93 %cmp2 = icmp eq i32 %x, %z
94 %r = select i1 %c, i1 %cmp1, i1 %cmp2
98 define i1 @icmp_eq_common_op11(i1 %c, i64 %x, i64 %y, i64 %z) {
99 ; CHECK-LABEL: @icmp_eq_common_op11(
100 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
101 ; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X:%.*]], [[R_V]]
102 ; CHECK-NEXT: ret i1 [[R]]
104 %cmp1 = icmp eq i64 %y, %x
105 %cmp2 = icmp eq i64 %z, %x
106 %r = select i1 %c, i1 %cmp1, i1 %cmp2
110 define i1 @icmp_common_one_use_1(i1 %c, i8 %x, i8 %y, i8 %z) {
111 ; CHECK-LABEL: @icmp_common_one_use_1(
112 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y:%.*]], [[X:%.*]]
113 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
114 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i8 [[Y]], i8 [[Z:%.*]]
115 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[R_V]]
116 ; CHECK-NEXT: ret i1 [[R]]
118 %cmp1 = icmp eq i8 %y, %x
119 call void @use(i1 %cmp1)
120 %cmp2 = icmp eq i8 %z, %x
121 %r = select i1 %c, i1 %cmp1, i1 %cmp2
125 define i1 @icmp_slt_common(i1 %c, i6 %x, i6 %y, i6 %z) {
126 ; CHECK-LABEL: @icmp_slt_common(
127 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
128 ; CHECK-NEXT: [[R:%.*]] = icmp slt i6 [[X:%.*]], [[R_V]]
129 ; CHECK-NEXT: ret i1 [[R]]
131 %cmp1 = icmp slt i6 %x, %y
132 %cmp2 = icmp slt i6 %x, %z
133 %r = select i1 %c, i1 %cmp1, i1 %cmp2
137 define i1 @icmp_sgt_common(i1 %c, i6 %x, i6 %y, i6 %z) {
138 ; CHECK-LABEL: @icmp_sgt_common(
139 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
140 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i6 [[X:%.*]], [[R_V]]
141 ; CHECK-NEXT: ret i1 [[R]]
143 %cmp1 = icmp sgt i6 %x, %y
144 %cmp2 = icmp sgt i6 %x, %z
145 %r = select i1 %c, i1 %cmp1, i1 %cmp2
149 define i1 @icmp_sle_common(i1 %c, i6 %x, i6 %y, i6 %z) {
150 ; CHECK-LABEL: @icmp_sle_common(
151 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
152 ; CHECK-NEXT: [[R:%.*]] = icmp sge i6 [[X:%.*]], [[R_V]]
153 ; CHECK-NEXT: ret i1 [[R]]
155 %cmp1 = icmp sle i6 %y, %x
156 %cmp2 = icmp sle i6 %z, %x
157 %r = select i1 %c, i1 %cmp1, i1 %cmp2
161 define i1 @icmp_sge_common(i1 %c, i6 %x, i6 %y, i6 %z) {
162 ; CHECK-LABEL: @icmp_sge_common(
163 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
164 ; CHECK-NEXT: [[R:%.*]] = icmp sle i6 [[X:%.*]], [[R_V]]
165 ; CHECK-NEXT: ret i1 [[R]]
167 %cmp1 = icmp sge i6 %y, %x
168 %cmp2 = icmp sge i6 %z, %x
169 %r = select i1 %c, i1 %cmp1, i1 %cmp2
173 define i1 @icmp_slt_sgt_common(i1 %c, i6 %x, i6 %y, i6 %z) {
174 ; CHECK-LABEL: @icmp_slt_sgt_common(
175 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
176 ; CHECK-NEXT: [[R:%.*]] = icmp slt i6 [[X:%.*]], [[R_V]]
177 ; CHECK-NEXT: ret i1 [[R]]
179 %cmp1 = icmp slt i6 %x, %y
180 %cmp2 = icmp sgt i6 %z, %x
181 %r = select i1 %c, i1 %cmp1, i1 %cmp2
185 define i1 @icmp_sle_sge_common(i1 %c, i6 %x, i6 %y, i6 %z) {
186 ; CHECK-LABEL: @icmp_sle_sge_common(
187 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
188 ; CHECK-NEXT: [[R:%.*]] = icmp sge i6 [[X:%.*]], [[R_V]]
189 ; CHECK-NEXT: ret i1 [[R]]
191 %cmp1 = icmp sle i6 %y, %x
192 %cmp2 = icmp sge i6 %x, %z
193 %r = select i1 %c, i1 %cmp1, i1 %cmp2
197 define i1 @icmp_ult_common(i1 %c, i6 %x, i6 %y, i6 %z) {
198 ; CHECK-LABEL: @icmp_ult_common(
199 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
200 ; CHECK-NEXT: [[R:%.*]] = icmp ult i6 [[X:%.*]], [[R_V]]
201 ; CHECK-NEXT: ret i1 [[R]]
203 %cmp1 = icmp ult i6 %x, %y
204 %cmp2 = icmp ult i6 %x, %z
205 %r = select i1 %c, i1 %cmp1, i1 %cmp2
209 define i1 @icmp_ule_common(i1 %c, i6 %x, i6 %y, i6 %z) {
210 ; CHECK-LABEL: @icmp_ule_common(
211 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
212 ; CHECK-NEXT: [[R:%.*]] = icmp uge i6 [[X:%.*]], [[R_V]]
213 ; CHECK-NEXT: ret i1 [[R]]
215 %cmp1 = icmp ule i6 %y, %x
216 %cmp2 = icmp ule i6 %z, %x
217 %r = select i1 %c, i1 %cmp1, i1 %cmp2
221 define i1 @icmp_ugt_common(i1 %c, i8 %x, i8 %y, i8 %z) {
222 ; CHECK-LABEL: @icmp_ugt_common(
223 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]
224 ; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[R_V]]
225 ; CHECK-NEXT: ret i1 [[R]]
227 %cmp1 = icmp ugt i8 %y, %x
228 %cmp2 = icmp ugt i8 %z, %x
229 %r = select i1 %c, i1 %cmp1, i1 %cmp2
233 define i1 @icmp_uge_common(i1 %c, i6 %x, i6 %y, i6 %z) {
234 ; CHECK-LABEL: @icmp_uge_common(
235 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
236 ; CHECK-NEXT: [[R:%.*]] = icmp ule i6 [[X:%.*]], [[R_V]]
237 ; CHECK-NEXT: ret i1 [[R]]
239 %cmp1 = icmp uge i6 %y, %x
240 %cmp2 = icmp uge i6 %z, %x
241 %r = select i1 %c, i1 %cmp1, i1 %cmp2
245 define i1 @icmp_ult_ugt_common(i1 %c, i6 %x, i6 %y, i6 %z) {
246 ; CHECK-LABEL: @icmp_ult_ugt_common(
247 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
248 ; CHECK-NEXT: [[R:%.*]] = icmp ult i6 [[X:%.*]], [[R_V]]
249 ; CHECK-NEXT: ret i1 [[R]]
251 %cmp1 = icmp ult i6 %x, %y
252 %cmp2 = icmp ugt i6 %z, %x
253 %r = select i1 %c, i1 %cmp1, i1 %cmp2
257 define i1 @icmp_ule_uge_common(i1 %c, i6 %x, i6 %y, i6 %z) {
258 ; CHECK-LABEL: @icmp_ule_uge_common(
259 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
260 ; CHECK-NEXT: [[R:%.*]] = icmp uge i6 [[X:%.*]], [[R_V]]
261 ; CHECK-NEXT: ret i1 [[R]]
263 %cmp1 = icmp ule i6 %y, %x
264 %cmp2 = icmp uge i6 %x, %z
265 %r = select i1 %c, i1 %cmp1, i1 %cmp2
269 ; negative test: pred is not the same
271 define i1 @icmp_common_pred_different(i1 %c, i8 %x, i8 %y, i8 %z) {
272 ; CHECK-LABEL: @icmp_common_pred_different(
273 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y:%.*]], [[X:%.*]]
274 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Z:%.*]], [[X]]
275 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
276 ; CHECK-NEXT: ret i1 [[R]]
278 %cmp1 = icmp eq i8 %y, %x
279 %cmp2 = icmp ne i8 %z, %x
280 %r = select i1 %c, i1 %cmp1, i1 %cmp2
284 ; negative test for non-equality: two pred is not swap
286 define i1 @icmp_common_pred_not_swap(i1 %c, i8 %x, i8 %y, i8 %z) {
287 ; CHECK-LABEL: @icmp_common_pred_not_swap(
288 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
289 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[Z:%.*]], [[X]]
290 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
291 ; CHECK-NEXT: ret i1 [[R]]
293 %cmp1 = icmp slt i8 %y, %x
294 %cmp2 = icmp sle i8 %z, %x
295 %r = select i1 %c, i1 %cmp1, i1 %cmp2
299 ; negative test for non-equality: not commute pred
301 define i1 @icmp_common_pred_not_commute_pred(i1 %c, i8 %x, i8 %y, i8 %z) {
302 ; CHECK-LABEL: @icmp_common_pred_not_commute_pred(
303 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
304 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[Z:%.*]], [[X]]
305 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
306 ; CHECK-NEXT: ret i1 [[R]]
308 %cmp1 = icmp slt i8 %y, %x
309 %cmp2 = icmp sgt i8 %z, %x
310 %r = select i1 %c, i1 %cmp1, i1 %cmp2
314 ; negative test: both icmp is not one-use
316 define i1 @icmp_common_one_use_0(i1 %c, i8 %x, i8 %y, i8 %z) {
317 ; CHECK-LABEL: @icmp_common_one_use_0(
318 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y:%.*]], [[X:%.*]]
319 ; CHECK-NEXT: call void @use(i1 [[CMP1]])
320 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[Z:%.*]], [[X]]
321 ; CHECK-NEXT: call void @use(i1 [[CMP2]])
322 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
323 ; CHECK-NEXT: ret i1 [[R]]
325 %cmp1 = icmp eq i8 %y, %x
326 call void @use(i1 %cmp1)
327 %cmp2 = icmp eq i8 %z, %x
328 call void @use(i1 %cmp2)
329 %r = select i1 %c, i1 %cmp1, i1 %cmp2
333 ; negative test: no common op
335 define i1 @icmp_no_common(i1 %c, i8 %x, i8 %y, i8 %z) {
336 ; CHECK-LABEL: @icmp_no_common(
337 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y:%.*]], 0
338 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[Z:%.*]], [[X:%.*]]
339 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
340 ; CHECK-NEXT: ret i1 [[R]]
342 %cmp1 = icmp eq i8 %y, 0
343 %cmp2 = icmp eq i8 %z, %x
344 %r = select i1 %c, i1 %cmp1, i1 %cmp2
348 define i1 @test_select_inverse_eq(i64 %x, i1 %y) {
349 ; CHECK-LABEL: @test_select_inverse_eq(
350 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[X:%.*]], 0
351 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[Y:%.*]], [[CMP2]]
352 ; CHECK-NEXT: ret i1 [[SEL]]
354 %cmp1 = icmp ne i64 %x, 0
355 %cmp2 = icmp eq i64 %x, 0
356 %sel = select i1 %y, i1 %cmp1, i1 %cmp2
360 define i1 @test_select_inverse_signed(i64 %x, i1 %y) {
361 ; CHECK-LABEL: @test_select_inverse_signed(
362 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[X:%.*]], 0
363 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[Y:%.*]], [[CMP2]]
364 ; CHECK-NEXT: ret i1 [[SEL]]
366 %cmp1 = icmp sgt i64 %x, -1
367 %cmp2 = icmp slt i64 %x, 0
368 %sel = select i1 %y, i1 %cmp1, i1 %cmp2
372 define i1 @test_select_inverse_unsigned(i64 %x, i1 %y) {
373 ; CHECK-LABEL: @test_select_inverse_unsigned(
374 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i64 [[X:%.*]], 10
375 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[Y:%.*]], [[CMP2]]
376 ; CHECK-NEXT: ret i1 [[SEL]]
378 %cmp1 = icmp ult i64 %x, 11
379 %cmp2 = icmp ugt i64 %x, 10
380 %sel = select i1 %y, i1 %cmp1, i1 %cmp2
384 define i1 @test_select_inverse_eq_ptr(ptr %x, i1 %y) {
385 ; CHECK-LABEL: @test_select_inverse_eq_ptr(
386 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne ptr [[X:%.*]], null
387 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[Y:%.*]], [[CMP2]]
388 ; CHECK-NEXT: ret i1 [[SEL]]
390 %cmp1 = icmp eq ptr %x, null
391 %cmp2 = icmp ne ptr %x, null
392 %sel = select i1 %y, i1 %cmp1, i1 %cmp2
396 define i1 @test_select_inverse_fail(i64 %x, i1 %y) {
397 ; CHECK-LABEL: @test_select_inverse_fail(
398 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[X:%.*]], 0
399 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[X]], 0
400 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[Y:%.*]], i1 [[CMP1]], i1 [[CMP2]]
401 ; CHECK-NEXT: ret i1 [[SEL]]
403 %cmp1 = icmp sgt i64 %x, 0
404 %cmp2 = icmp slt i64 %x, 0
405 %sel = select i1 %y, i1 %cmp1, i1 %cmp2
409 define <2 x i1> @test_select_inverse_vec(<2 x i64> %x, <2 x i1> %y) {
410 ; CHECK-LABEL: @test_select_inverse_vec(
411 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i64> [[X:%.*]], zeroinitializer
412 ; CHECK-NEXT: [[SEL:%.*]] = xor <2 x i1> [[Y:%.*]], [[CMP2]]
413 ; CHECK-NEXT: ret <2 x i1> [[SEL]]
415 %cmp1 = icmp ne <2 x i64> %x, zeroinitializer
416 %cmp2 = icmp eq <2 x i64> %x, zeroinitializer
417 %sel = select <2 x i1> %y, <2 x i1> %cmp1, <2 x i1> %cmp2
421 define <2 x i1> @test_select_inverse_vec_fail(<2 x i64> %x, i1 %y) {
422 ; CHECK-LABEL: @test_select_inverse_vec_fail(
423 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer
424 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i64> [[X]], zeroinitializer
425 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[Y:%.*]], <2 x i1> [[CMP1]], <2 x i1> [[CMP2]]
426 ; CHECK-NEXT: ret <2 x i1> [[SEL]]
428 %cmp1 = icmp ne <2 x i64> %x, zeroinitializer
429 %cmp2 = icmp eq <2 x i64> %x, zeroinitializer
430 %sel = select i1 %y, <2 x i1> %cmp1, <2 x i1> %cmp2
434 define i1 @test_select_inverse_nonconst1(i64 %x, i64 %y, i1 %cond) {
435 ; CHECK-LABEL: @test_select_inverse_nonconst1(
436 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
437 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
438 ; CHECK-NEXT: ret i1 [[SEL]]
440 %cmp1 = icmp ne i64 %x, %y
441 %cmp2 = icmp eq i64 %x, %y
442 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
446 define i1 @test_select_inverse_nonconst2(i64 %x, i64 %y, i1 %cond) {
447 ; CHECK-LABEL: @test_select_inverse_nonconst2(
448 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
449 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
450 ; CHECK-NEXT: ret i1 [[SEL]]
452 %cmp1 = icmp ne i64 %x, %y
453 %cmp2 = icmp eq i64 %y, %x
454 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
458 define i1 @test_select_inverse_nonconst3(i64 %x, i64 %y, i1 %cond) {
459 ; CHECK-LABEL: @test_select_inverse_nonconst3(
460 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i64 [[X:%.*]], [[Y:%.*]]
461 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
462 ; CHECK-NEXT: ret i1 [[SEL]]
464 %cmp1 = icmp ult i64 %x, %y
465 %cmp2 = icmp uge i64 %x, %y
466 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
470 define i1 @test_select_inverse_nonconst4(i64 %x, i64 %y, i64 %z, i1 %cond) {
471 ; CHECK-LABEL: @test_select_inverse_nonconst4(
472 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]]
473 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i64 [[Z:%.*]], [[Y]]
474 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
475 ; CHECK-NEXT: ret i1 [[SEL]]
477 %cmp1 = icmp ult i64 %x, %y
478 %cmp2 = icmp uge i64 %z, %y
479 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
483 define i1 @test_select_inverse_samesign_true_arm(i64 %x, i64 %y, i1 %cond) {
484 ; CHECK-LABEL: @test_select_inverse_samesign_true_arm(
485 ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ult i64 [[X:%.*]], [[Y:%.*]]
486 ; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i64 [[X]], [[Y]]
487 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
488 ; CHECK-NEXT: ret i1 [[SEL]]
490 %cmp1 = icmp samesign ult i64 %x, %y
491 %cmp2 = icmp uge i64 %x, %y
492 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
496 define i1 @test_select_inverse_samesign_false_arm(i64 %x, i64 %y, i1 %cond) {
497 ; CHECK-LABEL: @test_select_inverse_samesign_false_arm(
498 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]]
499 ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign uge i64 [[X]], [[Y]]
500 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
501 ; CHECK-NEXT: ret i1 [[SEL]]
503 %cmp1 = icmp ult i64 %x, %y
504 %cmp2 = icmp samesign uge i64 %x, %y
505 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
509 define i1 @test_select_inverse_samesign_both(i64 %x, i64 %y, i1 %cond) {
510 ; CHECK-LABEL: @test_select_inverse_samesign_both(
511 ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign uge i64 [[X:%.*]], [[Y:%.*]]
512 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
513 ; CHECK-NEXT: ret i1 [[SEL]]
515 %cmp1 = icmp samesign ult i64 %x, %y
516 %cmp2 = icmp samesign uge i64 %x, %y
517 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
521 define i1 @test_select_inverse_samesign_false_arm_rhsc_same_sign(i64 %x, i64 %y, i1 %cond) {
522 ; CHECK-LABEL: @test_select_inverse_samesign_false_arm_rhsc_same_sign(
523 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[X:%.*]], 11
524 ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ugt i64 [[X]], 10
525 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
526 ; CHECK-NEXT: ret i1 [[SEL]]
528 %cmp1 = icmp ult i64 %x, 11
529 %cmp2 = icmp samesign ugt i64 %x, 10
530 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
534 define i1 @test_select_inverse_samesign_true_arm_rhsc_same_sign(i64 %x, i64 %y, i1 %cond) {
535 ; CHECK-LABEL: @test_select_inverse_samesign_true_arm_rhsc_same_sign(
536 ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ult i64 [[X:%.*]], 11
537 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i64 [[X]], 10
538 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
539 ; CHECK-NEXT: ret i1 [[SEL]]
541 %cmp1 = icmp samesign ult i64 %x, 11
542 %cmp2 = icmp ugt i64 %x, 10
543 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
547 define i1 @test_select_inverse_samesign_both_rhsc_same_sign(i64 %x, i64 %y, i1 %cond) {
548 ; CHECK-LABEL: @test_select_inverse_samesign_both_rhsc_same_sign(
549 ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ugt i64 [[X:%.*]], 10
550 ; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
551 ; CHECK-NEXT: ret i1 [[SEL]]
553 %cmp1 = icmp samesign ult i64 %x, 11
554 %cmp2 = icmp samesign ugt i64 %x, 10
555 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
559 define i1 @test_select_inverse_samesign_both_rhsc_diff_sign(i64 %x, i64 %y, i1 %cond) {
560 ; CHECK-LABEL: @test_select_inverse_samesign_both_rhsc_diff_sign(
561 ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign slt i64 [[X:%.*]], 0
562 ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign sgt i64 [[X]], -1
563 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
564 ; CHECK-NEXT: ret i1 [[SEL]]
566 %cmp1 = icmp samesign slt i64 %x, 0
567 %cmp2 = icmp samesign sgt i64 %x, -1
568 %sel = select i1 %cond, i1 %cmp1, i1 %cmp2
572 define i1 @sel_icmp_two_cmp(i1 %c, i32 %a1, i32 %a2, i32 %a3, i32 %a4) {
573 ; CHECK-LABEL: @sel_icmp_two_cmp(
574 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i32 [[A1:%.*]], [[A2:%.*]]
575 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[A3:%.*]], [[A4:%.*]]
576 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
577 ; CHECK-NEXT: ret i1 [[CMP]]
579 %v1 = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
580 %v2 = call i8 @llvm.scmp(i32 %a3, i32 %a4)
581 %sel = select i1 %c, i8 %v1, i8 %v2
582 %cmp = icmp sle i8 %sel, 0
586 define i1 @sel_icmp_two_cmp_extra_use1(i1 %c, i32 %a1, i32 %a2, i32 %a3, i32 %a4) {
587 ; CHECK-LABEL: @sel_icmp_two_cmp_extra_use1(
588 ; CHECK-NEXT: [[V1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A1:%.*]], i32 [[A2:%.*]])
589 ; CHECK-NEXT: call void @use.i8(i8 [[V1]])
590 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i32 [[A1]], [[A2]]
591 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[A3:%.*]], [[A4:%.*]]
592 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
593 ; CHECK-NEXT: ret i1 [[CMP]]
595 %v1 = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
596 %v2 = call i8 @llvm.scmp(i32 %a3, i32 %a4)
597 call void @use.i8(i8 %v1)
598 %sel = select i1 %c, i8 %v1, i8 %v2
599 %cmp = icmp sle i8 %sel, 0
603 define i1 @sel_icmp_two_cmp_extra_use2(i1 %c, i32 %a1, i32 %a2, i32 %a3, i32 %a4) {
604 ; CHECK-LABEL: @sel_icmp_two_cmp_extra_use2(
605 ; CHECK-NEXT: [[V1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A1:%.*]], i32 [[A2:%.*]])
606 ; CHECK-NEXT: [[V2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A3:%.*]], i32 [[A4:%.*]])
607 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8 [[V1]], i8 [[V2]]
608 ; CHECK-NEXT: call void @use.i8(i8 [[SEL]])
609 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SEL]], 1
610 ; CHECK-NEXT: ret i1 [[CMP]]
612 %v1 = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
613 %v2 = call i8 @llvm.scmp(i32 %a3, i32 %a4)
614 %sel = select i1 %c, i8 %v1, i8 %v2
615 call void @use.i8(i8 %sel)
616 %cmp = icmp sle i8 %sel, 0
620 define i1 @sel_icmp_two_cmp_not_const(i1 %c, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i8 %b) {
621 ; CHECK-LABEL: @sel_icmp_two_cmp_not_const(
622 ; CHECK-NEXT: [[V1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A1:%.*]], i32 [[A2:%.*]])
623 ; CHECK-NEXT: [[V2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A3:%.*]], i32 [[A4:%.*]])
624 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8 [[V1]], i8 [[V2]]
625 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[SEL]], [[B:%.*]]
626 ; CHECK-NEXT: ret i1 [[CMP]]
628 %v1 = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
629 %v2 = call i8 @llvm.scmp(i32 %a3, i32 %a4)
630 %sel = select i1 %c, i8 %v1, i8 %v2
631 %cmp = icmp sle i8 %sel, %b
635 define <2 x i1> @sel_icmp_two_cmp_vec(i1 %c, <2 x i32> %a1, <2 x i32> %a2, <2 x i32> %a3, <2 x i32> %a4) {
636 ; CHECK-LABEL: @sel_icmp_two_cmp_vec(
637 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ule <2 x i32> [[A1:%.*]], [[A2:%.*]]
638 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sle <2 x i32> [[A3:%.*]], [[A4:%.*]]
639 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[C:%.*]], <2 x i1> [[CMP1]], <2 x i1> [[CMP2]]
640 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
642 %v1 = call <2 x i8> @llvm.ucmp(<2 x i32> %a1, <2 x i32> %a2)
643 %v2 = call <2 x i8> @llvm.scmp(<2 x i32> %a3, <2 x i32> %a4)
644 %sel = select i1 %c, <2 x i8> %v1, <2 x i8> %v2
645 %cmp = icmp sle <2 x i8> %sel, zeroinitializer
649 define <2 x i1> @sel_icmp_two_cmp_vec_nonsplat(i1 %c, <2 x i32> %a1, <2 x i32> %a2, <2 x i32> %a3, <2 x i32> %a4) {
650 ; CHECK-LABEL: @sel_icmp_two_cmp_vec_nonsplat(
651 ; CHECK-NEXT: [[V1:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A1:%.*]], <2 x i32> [[A2:%.*]])
652 ; CHECK-NEXT: [[V2:%.*]] = call <2 x i8> @llvm.scmp.v2i8.v2i32(<2 x i32> [[A3:%.*]], <2 x i32> [[A4:%.*]])
653 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], <2 x i8> [[V1]], <2 x i8> [[V2]]
654 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[SEL]], <i8 1, i8 2>
655 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
657 %v1 = call <2 x i8> @llvm.ucmp(<2 x i32> %a1, <2 x i32> %a2)
658 %v2 = call <2 x i8> @llvm.scmp(<2 x i32> %a3, <2 x i32> %a4)
659 %sel = select i1 %c, <2 x i8> %v1, <2 x i8> %v2
660 %cmp = icmp sle <2 x i8> %sel, <i8 0, i8 1>
664 define i1 @sel_icmp_cmp_and_simplify(i1 %c, i32 %a1, i32 %a2) {
665 ; CHECK-LABEL: @sel_icmp_cmp_and_simplify(
666 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i32 [[A1:%.*]], [[A2:%.*]]
667 ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
668 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[CMP1]]
669 ; CHECK-NEXT: ret i1 [[CMP]]
671 %v = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
672 %sel = select i1 %c, i8 %v, i8 0
673 %cmp = icmp sle i8 %sel, 0
677 define i1 @sel_icmp_cmp_and_no_simplify(i1 %c, i32 %a1, i32 %a2, i8 %b) {
678 ; CHECK-LABEL: @sel_icmp_cmp_and_no_simplify(
679 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i32 [[A1:%.*]], [[A2:%.*]]
680 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 [[B:%.*]], 1
681 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
682 ; CHECK-NEXT: ret i1 [[CMP]]
684 %v = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
685 %sel = select i1 %c, i8 %v, i8 %b
686 %cmp = icmp sle i8 %sel, 0
690 define i1 @sel_icmp_cmp_and_no_simplify_comm(i1 %c, i32 %a1, i32 %a2, i8 %b) {
691 ; CHECK-LABEL: @sel_icmp_cmp_and_no_simplify_comm(
692 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[B:%.*]], 1
693 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[A1:%.*]], [[A2:%.*]]
694 ; CHECK-NEXT: [[CMP:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
695 ; CHECK-NEXT: ret i1 [[CMP]]
697 %v = call i8 @llvm.ucmp(i32 %a1, i32 %a2)
698 %sel = select i1 %c, i8 %b, i8 %v
699 %cmp = icmp sle i8 %sel, 0
703 declare void @use(i1)
704 declare void @use.i8(i8)