1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 define i1 @logical_and_of_or_commute0(i1 %x, i1 %y) {
5 ; CHECK-LABEL: @logical_and_of_or_commute0(
6 ; CHECK-NEXT: ret i1 [[X:%.*]]
9 %xory = select i1 %x, i1 true, i1 %y
10 %xorynot = select i1 %x, i1 true, i1 %ynot
11 %and = select i1 %xory, i1 %xorynot, i1 false
15 define <2 x i1> @logical_and_of_or_commute1(<2 x i1> %x, <2 x i1> %y) {
16 ; CHECK-LABEL: @logical_and_of_or_commute1(
17 ; CHECK-NEXT: ret <2 x i1> [[X:%.*]]
19 %ynot = xor <2 x i1> %y, <i1 -1, i1 poison>
20 %xory = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
21 %xorynot = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %ynot
22 %and = select <2 x i1> %xory, <2 x i1> %xorynot, <2 x i1> zeroinitializer
26 define i1 @logical_and_of_or_commute2(i1 %x, i1 %y) {
27 ; CHECK-LABEL: @logical_and_of_or_commute2(
28 ; CHECK-NEXT: ret i1 [[X:%.*]]
31 %xory = select i1 %x, i1 true, i1 %y
32 %xorynot = select i1 %ynot, i1 true, i1 %x
33 %and = select i1 %xory, i1 %xorynot, i1 false
37 define i1 @logical_and_of_or_commute3(i1 %x, i1 %y) {
38 ; CHECK-LABEL: @logical_and_of_or_commute3(
39 ; CHECK-NEXT: ret i1 [[X:%.*]]
42 %xory = select i1 %y, i1 true, i1 %x
43 %xorynot = select i1 %ynot, i1 true, i1 %x
44 %and = select i1 %xory, i1 %xorynot, i1 false
48 define i1 @logical_and_of_or_commute4(i1 %x, i1 %y) {
49 ; CHECK-LABEL: @logical_and_of_or_commute4(
50 ; CHECK-NEXT: ret i1 [[X:%.*]]
53 %xory = select i1 %x, i1 true, i1 %y
54 %xorynot = select i1 %x, i1 true, i1 %ynot
55 %and = select i1 %xorynot, i1 %xory, i1 false
59 define i1 @logical_and_of_or_commute5(i1 %x, i1 %y) {
60 ; CHECK-LABEL: @logical_and_of_or_commute5(
61 ; CHECK-NEXT: ret i1 [[X:%.*]]
64 %xory = select i1 %y, i1 true, i1 %x
65 %xorynot = select i1 %x, i1 true, i1 %ynot
66 %and = select i1 %xorynot, i1 %xory, i1 false
70 define i1 @logical_and_of_or_commute6(i1 %x, i1 %y) {
71 ; CHECK-LABEL: @logical_and_of_or_commute6(
72 ; CHECK-NEXT: ret i1 [[X:%.*]]
75 %xory = select i1 %x, i1 true, i1 %y
76 %xorynot = select i1 %ynot, i1 true, i1 %x
77 %and = select i1 %xorynot, i1 %xory, i1 false
81 define i1 @logical_and_of_or_commute7(i1 %x, i1 %y) {
82 ; CHECK-LABEL: @logical_and_of_or_commute7(
83 ; CHECK-NEXT: ret i1 [[X:%.*]]
86 %xory = select i1 %y, i1 true, i1 %x
87 %xorynot = select i1 %ynot, i1 true, i1 %x
88 %and = select i1 %xorynot, i1 %xory, i1 false
92 ; negative test - wrong logic op
94 define i1 @logical_and_of_or_and(i1 %x, i1 %y) {
95 ; CHECK-LABEL: @logical_and_of_or_and(
96 ; CHECK-NEXT: [[XANDY:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false
97 ; CHECK-NEXT: [[YNOT:%.*]] = xor i1 [[Y]], true
98 ; CHECK-NEXT: [[XORYNOT:%.*]] = select i1 [[YNOT]], i1 true, i1 [[X]]
99 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[XORYNOT]], i1 [[XANDY]], i1 false
100 ; CHECK-NEXT: ret i1 [[AND]]
102 %xandy = select i1 %y, i1 %x, i1 false
103 %ynot = xor i1 %y, -1
104 %xorynot = select i1 %ynot, i1 true, i1 %x
105 %and = select i1 %xorynot, i1 %xandy, i1 false
109 ; negative test - must have common operands
111 define i1 @logical_and_of_or_no_common_op(i1 %x, i1 %y, i1 %z) {
112 ; CHECK-LABEL: @logical_and_of_or_no_common_op(
113 ; CHECK-NEXT: [[XORZ:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Z:%.*]]
114 ; CHECK-NEXT: [[YNOT:%.*]] = xor i1 [[Y:%.*]], true
115 ; CHECK-NEXT: [[XORYNOT:%.*]] = select i1 [[X]], i1 true, i1 [[YNOT]]
116 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[XORYNOT]], i1 [[XORZ]], i1 false
117 ; CHECK-NEXT: ret i1 [[AND]]
119 %xorz = select i1 %x, i1 true, i1 %z
120 %ynot = xor i1 %y, -1
121 %xorynot = select i1 %x, i1 true, i1 %ynot
122 %and = select i1 %xorynot, i1 %xorz, i1 false
126 ; !(X | Y) && X --> false
128 define i1 @or_not_and(i1 %x, i1 %y) {
129 ; CHECK-LABEL: @or_not_and(
130 ; CHECK-NEXT: ret i1 false
132 %l.and = or i1 %x, %y
133 %not = xor i1 %l.and, true
134 %r = select i1 %not, i1 %x, i1 false
138 ; vector case !(X | Y) && X --> false
140 define <2 x i1> @or_not_and_vector(<2 x i1> %x, <2 x i1> %y) {
141 ; CHECK-LABEL: @or_not_and_vector(
142 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
144 %l.and = or <2 x i1> %x, %y
145 %not = xor <2 x i1> %l.and, <i1 true, i1 true>
146 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 false, i1 false>
150 ; vector case !(X | Y) && X --> false
152 define <2 x i1> @or_not_and_vector_poison1(<2 x i1> %x, <2 x i1> %y) {
153 ; CHECK-LABEL: @or_not_and_vector_poison1(
154 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
156 %l.and = or <2 x i1> %x, %y
157 %not = xor <2 x i1> %l.and, <i1 poison, i1 true>
158 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 false, i1 false>
162 ; vector case !(X | Y) && X --> false
164 define <2 x i1> @or_not_and_vector_poison2(<2 x i1> %x, <2 x i1> %y) {
165 ; CHECK-LABEL: @or_not_and_vector_poison2(
166 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
168 %l.and = or <2 x i1> %x, %y
169 %not = xor <2 x i1> %l.and, <i1 true, i1 true>
170 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 poison, i1 false>
175 ; !(X || Y) && X --> false
177 define i1 @logical_or_not_and(i1 %x, i1 %y) {
178 ; CHECK-LABEL: @logical_or_not_and(
179 ; CHECK-NEXT: ret i1 false
181 %l.and = select i1 %x, i1 true, i1 %y
182 %not = xor i1 %l.and, true
183 %r = select i1 %not, i1 %x, i1 false
187 ; !(X || Y) && Y --> false
189 define i1 @logical_or_not_and_commute_or(i1 %x, i1 %y) {
190 ; CHECK-LABEL: @logical_or_not_and_commute_or(
191 ; CHECK-NEXT: ret i1 false
193 %l.and = select i1 %x, i1 true, i1 %y
194 %not = xor i1 %l.and, true
195 %r = select i1 %not, i1 %y, i1 false
199 ; X && !(X || Y) --> false
201 define i1 @logical_or_not_commute_and(i1 %x, i1 %y) {
202 ; CHECK-LABEL: @logical_or_not_commute_and(
203 ; CHECK-NEXT: ret i1 false
205 %l.and = select i1 %x, i1 true, i1 %y
206 %not = xor i1 %l.and, true
207 %r = select i1 %x, i1 %not, i1 false
211 ; Y && !(X || Y) --> false
213 define i1 @logical_or_not_commute_and_commute_or(i1 %x, i1 %y) {
214 ; CHECK-LABEL: @logical_or_not_commute_and_commute_or(
215 ; CHECK-NEXT: ret i1 false
217 %l.and = select i1 %x, i1 true, i1 %y
218 %not = xor i1 %l.and, true
219 %r = select i1 %y, i1 %not, i1 false
223 ; vector case !(X || Y) && X --> false
225 define <3 x i1> @logical_or_not_and_vector1(<3 x i1> %x, <3 x i1> %y) {
226 ; CHECK-LABEL: @logical_or_not_and_vector1(
227 ; CHECK-NEXT: ret <3 x i1> zeroinitializer
229 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y
230 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true>
231 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false>
235 ; TODO: this could transform to false
236 ; vector case !(X || Y) && X --> false
238 define <3 x i1> @logical_or_not_and_vector1_poison1(<3 x i1> %x, <3 x i1> %y) {
239 ; CHECK-LABEL: @logical_or_not_and_vector1_poison1(
240 ; CHECK-NEXT: [[L_AND:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> [[Y:%.*]]
241 ; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i1> [[L_AND]], <i1 true, i1 true, i1 true>
242 ; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> zeroinitializer
243 ; CHECK-NEXT: ret <3 x i1> [[R]]
245 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> %y
246 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true>
247 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false>
251 ; vector case !(X || Y) && X --> false
253 define <3 x i1> @logical_or_not_and_vector1_poison2(<3 x i1> %x, <3 x i1> %y) {
254 ; CHECK-LABEL: @logical_or_not_and_vector1_poison2(
255 ; CHECK-NEXT: ret <3 x i1> zeroinitializer
257 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y
258 %not = xor <3 x i1> %l.and, <i1 true, i1 poison, i1 true>
259 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false>
263 ; vector case !(X || Y) && X --> false
265 define <3 x i1> @logical_or_not_and_vector1_poison3(<3 x i1> %x, <3 x i1> %y) {
266 ; CHECK-LABEL: @logical_or_not_and_vector1_poison3(
267 ; CHECK-NEXT: ret <3 x i1> zeroinitializer
269 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y
270 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true>
271 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 poison, i1 false, i1 false>
275 ; negative test - must have common operands
277 define i1 @logical_not_or_and_negative1(i1 %x, i1 %y, i1 %z) {
278 ; CHECK-LABEL: @logical_not_or_and_negative1(
279 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
280 ; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[Z:%.*]]
281 ; CHECK-NEXT: ret i1 [[R]]
284 %r = select i1 %or, i1 false, i1 %z
288 ; !(x && y) || x --> true
290 define i1 @logical_nand_logical_or_common_op_commute1(i1 %x, i1 %y) {
291 ; CHECK-LABEL: @logical_nand_logical_or_common_op_commute1(
292 ; CHECK-NEXT: ret i1 true
294 %and = select i1 %x, i1 %y, i1 false
295 %nand = xor i1 %and, -1
296 %or = select i1 %nand, i1 true, i1 %x
300 define <2 x i1> @logical_nand_logical_or_common_op_commute2(<2 x i1> %x, <2 x i1> %y) {
301 ; CHECK-LABEL: @logical_nand_logical_or_common_op_commute2(
302 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
304 %and = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer
305 %nand = xor <2 x i1> %and, <i1 -1, i1 -1>
306 %or = select <2 x i1> %nand, <2 x i1> <i1 -1, i1 -1>, <2 x i1> %x
310 define <2 x i1> @logical_nand_logical_or_common_op_commute3(<2 x i1> %x, <2 x i1> %y) {
311 ; CHECK-LABEL: @logical_nand_logical_or_common_op_commute3(
312 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
314 %and = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer
315 %nand = xor <2 x i1> %and, <i1 -1, i1 poison>
316 %or = select <2 x i1> %x, <2 x i1> <i1 -1, i1 poison>, <2 x i1> %nand
320 define i1 @logical_nand_logical_or_common_op_commute4(i1 %x, i1 %y) {
321 ; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4(
322 ; CHECK-NEXT: ret i1 true
324 %and = select i1 %y, i1 %x, i1 false
325 %nand = xor i1 %and, -1
326 %or = select i1 %x, i1 true, i1 %nand
330 ; TODO: This could fold the same as above (we don't match a partial poison vector as logical op).
332 define <2 x i1> @logical_nand_logical_or_common_op_commute4_poison_vec(<2 x i1> %x, <2 x i1> %y) {
333 ; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4_poison_vec(
334 ; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> [[X:%.*]], <2 x i1> <i1 false, i1 poison>
335 ; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i1> [[AND]], <i1 true, i1 true>
336 ; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[X]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[NAND]]
337 ; CHECK-NEXT: ret <2 x i1> [[OR]]
339 %and = select <2 x i1> %y, <2 x i1> %x, <2 x i1> <i1 0, i1 poison>
340 %nand = xor <2 x i1> %and, <i1 -1, i1 -1>
341 %or = select <2 x i1> %x, <2 x i1> <i1 -1, i1 -1>, <2 x i1> %nand
345 ; negative test - need common operand
347 define i1 @logical_nand_logical_or(i1 %x, i1 %y, i1 %z) {
348 ; CHECK-LABEL: @logical_nand_logical_or(
349 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
350 ; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true
351 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[NAND]], i1 true, i1 [[Z:%.*]]
352 ; CHECK-NEXT: ret i1 [[OR]]
354 %and = select i1 %x, i1 %y, i1 false
355 %nand = xor i1 %and, -1
356 %or = select i1 %nand, i1 true, i1 %z
360 ; (X | Y) ? false : X --> false
362 define i1 @or_select_false_x_case1(i1 %x, i1 %y) {
363 ; CHECK-LABEL: @or_select_false_x_case1(
364 ; CHECK-NEXT: ret i1 false
367 %r = select i1 %or, i1 false, i1 %x
371 ; (X | Y) ? false : X --> false
373 define i1 @or_select_false_x_case2(i1 %x, i1 %y) {
374 ; CHECK-LABEL: @or_select_false_x_case2(
375 ; CHECK-NEXT: ret i1 false
378 %r = select i1 %or, i1 false, i1 %y
382 ; vector case (X | Y) ? false : X --> false
384 define <2 x i1> @or_select_false_x_vector(<2 x i1> %x, <2 x i1> %y) {
385 ; CHECK-LABEL: @or_select_false_x_vector(
386 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
388 %or = or <2 x i1> %x, %y
389 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x
393 ; vector poison case (X | Y) ? false : X --> false
395 define <2 x i1> @or_select_false_x_vector_poison(<2 x i1> %x, <2 x i1> %y) {
396 ; CHECK-LABEL: @or_select_false_x_vector_poison(
397 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
399 %or = or <2 x i1> %x, %y
400 %r = select <2 x i1> %or, <2 x i1> <i1 poison, i1 false>, <2 x i1> %x
404 ; (X || Y) ? false : X --> false
406 define i1 @logical_or_select_false_x_case1(i1 %x, i1 %y) {
407 ; CHECK-LABEL: @logical_or_select_false_x_case1(
408 ; CHECK-NEXT: ret i1 false
410 %or = select i1 %x, i1 true, i1 %y
411 %r = select i1 %or, i1 false, i1 %x
415 ; (X || Y) ? false : X --> false
417 define i1 @logical_or_select_false_x_case2(i1 %x, i1 %y) {
418 ; CHECK-LABEL: @logical_or_select_false_x_case2(
419 ; CHECK-NEXT: ret i1 false
421 %or = select i1 %y, i1 true, i1 %x
422 %r = select i1 %or, i1 false, i1 %x
426 ; vector case (X || Y) ? false : X --> false
428 define <2 x i1> @logical_or_select_false_x_vector(<2 x i1> %x, <2 x i1> %y) {
429 ; CHECK-LABEL: @logical_or_select_false_x_vector(
430 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
432 %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
433 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x
437 ; TODO: this could transform to false
438 ; vector poison case (X || Y) ? false : X --> false
440 define <2 x i1> @logical_or_select_false_x_vector_poison1(<2 x i1> %x, <2 x i1> %y) {
441 ; CHECK-LABEL: @logical_or_select_false_x_vector_poison1(
442 ; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]]
443 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[OR]], <2 x i1> zeroinitializer, <2 x i1> [[X]]
444 ; CHECK-NEXT: ret <2 x i1> [[R]]
446 %or = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %x
447 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x
451 ; vector poison case (X || Y) ? false : X --> false
453 define <2 x i1> @logical_or_select_false_x_vector_poison2(<2 x i1> %x, <2 x i1> %y) {
454 ; CHECK-LABEL: @logical_or_select_false_x_vector_poison2(
455 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
457 %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
458 %r = select <2 x i1> %or, <2 x i1> <i1 poison, i1 false>, <2 x i1> %x
462 ; negative test - must have common operands
464 define i1 @or_select_false_x_negative(i1 %x, i1 %y, i1 %z) {
465 ; CHECK-LABEL: @or_select_false_x_negative(
466 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
467 ; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[Z:%.*]]
468 ; CHECK-NEXT: ret i1 [[R]]
471 %r = select i1 %or, i1 false, i1 %z
475 ; (X || Y) ? X : Y --> X
477 define i1 @select_or_same_op(i1 %x, i1 %y) {
478 ; CHECK-LABEL: @select_or_same_op(
479 ; CHECK-NEXT: ret i1 [[X:%.*]]
482 %r = select i1 %or, i1 %x, i1 %y
487 define i1 @select_or_same_op_commute(i1 %x, i1 %y) {
488 ; CHECK-LABEL: @select_or_same_op_commute(
489 ; CHECK-NEXT: ret i1 [[Y:%.*]]
492 %r = select i1 %or, i1 %y, i1 %x
497 define <2 x i1> @select_or_same_op_vector1(<2 x i1> %x, <2 x i1> %y) {
498 ; CHECK-LABEL: @select_or_same_op_vector1(
499 ; CHECK-NEXT: ret <2 x i1> [[X:%.*]]
501 %or = or <2 x i1> %x, %y
502 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y
507 define i1 @select_logic_or1_same_op(i1 %x, i1 %y) {
508 ; CHECK-LABEL: @select_logic_or1_same_op(
509 ; CHECK-NEXT: ret i1 [[X:%.*]]
511 %or = select i1 %x, i1 true, i1 %y
512 %r = select i1 %or, i1 %x, i1 %y
517 define i1 @select_logic_or2_same_op(i1 %x, i1 %y) {
518 ; CHECK-LABEL: @select_logic_or2_same_op(
519 ; CHECK-NEXT: ret i1 [[X:%.*]]
521 %or = select i1 %y, i1 true, i1 %x
522 %r = select i1 %or, i1 %x, i1 %y
527 define <2 x i1> @select_or_same_op_vector2(<2 x i1> %x, <2 x i1> %y) {
528 ; CHECK-LABEL: @select_or_same_op_vector2(
529 ; CHECK-NEXT: ret <2 x i1> [[X:%.*]]
531 %or = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %y
532 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y
536 ; TODO: this could transform to X
537 ; (X || Y) ? X : Y --> X
539 define <2 x i1> @select_or_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) {
540 ; CHECK-LABEL: @select_or_same_op_vector2_poison(
541 ; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> <i1 true, i1 poison>, <2 x i1> [[Y:%.*]]
542 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[OR]], <2 x i1> [[X]], <2 x i1> [[Y]]
543 ; CHECK-NEXT: ret <2 x i1> [[R]]
545 %or = select <2 x i1> %x, <2 x i1> <i1 true, i1 poison>, <2 x i1> %y
546 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y
550 ; negative test - must have common operands
552 define i1 @select_or_same_op_negative(i1 %x, i1 %y, i1 %z) {
553 ; CHECK-LABEL: @select_or_same_op_negative(
554 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
555 ; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 [[X]], i1 [[Z:%.*]]
556 ; CHECK-NEXT: ret i1 [[R]]
559 %r = select i1 %or, i1 %x, i1 %z
563 ; (X && Y) ? X : Y --> Y
565 define i1 @select_and_same_op(i1 %x, i1 %y) {
566 ; CHECK-LABEL: @select_and_same_op(
567 ; CHECK-NEXT: ret i1 [[Y:%.*]]
570 %r = select i1 %a, i1 %x, i1 %y
575 define i1 @select_and_same_op_commute(i1 %x, i1 %y) {
576 ; CHECK-LABEL: @select_and_same_op_commute(
577 ; CHECK-NEXT: ret i1 [[X:%.*]]
580 %r = select i1 %a, i1 %y, i1 %x
585 define <2 x i1> @select_and_same_op_vector1(<2 x i1> %x, <2 x i1> %y) {
586 ; CHECK-LABEL: @select_and_same_op_vector1(
587 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
589 %a = and <2 x i1> %x, %y
590 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y
595 define i1 @select_logic_and1_same_op(i1 %x, i1 %y) {
596 ; CHECK-LABEL: @select_logic_and1_same_op(
597 ; CHECK-NEXT: ret i1 [[Y:%.*]]
599 %a = select i1 %x, i1 %y, i1 false
600 %r = select i1 %a, i1 %x, i1 %y
605 define i1 @select_logic_and2_same_op(i1 %x, i1 %y) {
606 ; CHECK-LABEL: @select_logic_and2_same_op(
607 ; CHECK-NEXT: ret i1 [[Y:%.*]]
609 %a = select i1 %y, i1 %x, i1 false
610 %r = select i1 %a, i1 %x, i1 %y
615 define <2 x i1> @select_and_same_op_vector2(<2 x i1> %x, <2 x i1> %y) {
616 ; CHECK-LABEL: @select_and_same_op_vector2(
617 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
619 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer
620 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y
624 ; TODO: this could transform to Y
625 ; (X && Y) ? X : Y --> Y
627 define <2 x i1> @select_and_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) {
628 ; CHECK-LABEL: @select_and_same_op_vector2_poison(
629 ; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> <i1 false, i1 poison>
630 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[X]], <2 x i1> [[Y]]
631 ; CHECK-NEXT: ret <2 x i1> [[R]]
633 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 false, i1 poison>
634 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y
638 ; negative test - must have common operands
640 define i1 @select_and_same_op_negative(i1 %x, i1 %y, i1 %z) {
641 ; CHECK-LABEL: @select_and_same_op_negative(
642 ; CHECK-NEXT: [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
643 ; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Z:%.*]]
644 ; CHECK-NEXT: ret i1 [[R]]
647 %r = select i1 %a, i1 %x, i1 %z
651 define i1 @and_same_op(i1 %x) {
652 ; CHECK-LABEL: @and_same_op(
653 ; CHECK-NEXT: ret i1 [[X:%.*]]
655 %r = select i1 %x, i1 %x, i1 false
659 define <2 x i1> @or_same_op(<2 x i1> %x) {
660 ; CHECK-LABEL: @or_same_op(
661 ; CHECK-NEXT: ret <2 x i1> [[X:%.*]]
663 %r = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
667 define <2 x i1> @always_true_same_op(<2 x i1> %x) {
668 ; CHECK-LABEL: @always_true_same_op(
669 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
671 %r = select <2 x i1> %x, <2 x i1> %x, <2 x i1> <i1 poison, i1 true>
675 define i1 @always_false_same_op(i1 %x) {
676 ; CHECK-LABEL: @always_false_same_op(
677 ; CHECK-NEXT: ret i1 false
679 %r = select i1 %x, i1 false, i1 %x
683 ; (X && Y) || Y --> Y
685 define i1 @or_and_common_op_commute0(i1 %x, i1 %y) {
686 ; CHECK-LABEL: @or_and_common_op_commute0(
687 ; CHECK-NEXT: ret i1 [[Y:%.*]]
689 %a = select i1 %x, i1 %y, i1 false
690 %r = select i1 %a, i1 true, i1 %y
694 define <2 x i1> @or_and_common_op_commute1(<2 x i1> %x, <2 x i1> %y) {
695 ; CHECK-LABEL: @or_and_common_op_commute1(
696 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
698 %a = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer
699 %r = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %y
703 define <2 x i1> @or_and_common_op_commute2(<2 x i1> %x, <2 x i1> %y) {
704 ; CHECK-LABEL: @or_and_common_op_commute2(
705 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
707 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer
708 %r = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %a
712 ; TODO: this could fold the same as above
714 define <2 x i1> @or_and_common_op_commute2_poison(<2 x i1> %x, <2 x i1> %y) {
715 ; CHECK-LABEL: @or_and_common_op_commute2_poison(
716 ; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> <i1 false, i1 poison>
717 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[A]]
718 ; CHECK-NEXT: ret <2 x i1> [[R]]
720 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 0, i1 poison>
721 %r = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %a
725 define <2 x i1> @or_and_common_op_commute3(<2 x i1> %x, <2 x i1> %y) {
726 ; CHECK-LABEL: @or_and_common_op_commute3(
727 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
729 %a = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer
730 %r = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %a
736 define i1 @or_and_not_common_op(i1 %x, i1 %y, i1 %z) {
737 ; CHECK-LABEL: @or_and_not_common_op(
738 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
739 ; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 true, i1 [[Z:%.*]]
740 ; CHECK-NEXT: ret i1 [[R]]
742 %a = select i1 %x, i1 %y, i1 false
743 %r = select i1 %a, i1 true, i1 %z
747 ; (X || Y) && Y --> Y
749 define i1 @and_or_common_op_commute0(i1 %x, i1 %y) {
750 ; CHECK-LABEL: @and_or_common_op_commute0(
751 ; CHECK-NEXT: ret i1 [[Y:%.*]]
753 %o = select i1 %x, i1 true, i1 %y
754 %r = select i1 %o, i1 %y, i1 false
758 define <2 x i1> @and_or_common_op_commute1(<2 x i1> %x, <2 x i1> %y) {
759 ; CHECK-LABEL: @and_or_common_op_commute1(
760 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
762 %o = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
763 %r = select <2 x i1> %o, <2 x i1> %y, <2 x i1> zeroinitializer
768 define <2 x i1> @and_or_common_op_commute2(<2 x i1> %x, <2 x i1> %y) {
769 ; CHECK-LABEL: @and_or_common_op_commute2(
770 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
772 %o = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %y
773 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> <i1 0, i1 poison>
777 define <2 x i1> @and_or_common_op_commute3(<2 x i1> %x, <2 x i1> %y) {
778 ; CHECK-LABEL: @and_or_common_op_commute3(
779 ; CHECK-NEXT: ret <2 x i1> [[Y:%.*]]
781 %o = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
782 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> zeroinitializer
786 ; TODO: this could fold the same as above
788 define <2 x i1> @and_or_common_op_commute3_poison(<2 x i1> %x, <2 x i1> %y) {
789 ; CHECK-LABEL: @and_or_common_op_commute3_poison(
790 ; CHECK-NEXT: [[O:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]]
791 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y]], <2 x i1> [[O]], <2 x i1> zeroinitializer
792 ; CHECK-NEXT: ret <2 x i1> [[R]]
794 %o = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %x
795 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> zeroinitializer
801 define i1 @and_or_not_common_op(i1 %x, i1 %y, i1 %z) {
802 ; CHECK-LABEL: @and_or_not_common_op(
803 ; CHECK-NEXT: [[O:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
804 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Z:%.*]], i1 [[O]], i1 false
805 ; CHECK-NEXT: ret i1 [[R]]
807 %o = select i1 %x, i1 true, i1 %y
808 %r = select i1 %z, i1 %o, i1 false