[ConstraintElim] Add support for decomposing gep nuw (#118639)
[llvm-project.git] / llvm / test / Transforms / InstSimplify / select-logical.ll
blob6b5cef7b8e26ce62862d23dc2e0bd4c862578f0a
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:%.*]]
8   %ynot = xor i1 %y, -1
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
12   ret i1 %and
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
23   ret <2 x i1> %and
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:%.*]]
30   %ynot = xor i1 %y, -1
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
34   ret i1 %and
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:%.*]]
41   %ynot = xor i1 %y, -1
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
45   ret i1 %and
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:%.*]]
52   %ynot = xor i1 %y, -1
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
56   ret i1 %and
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:%.*]]
63   %ynot = xor i1 %y, -1
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
67   ret i1 %and
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:%.*]]
74   %ynot = xor i1 %y, -1
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
78   ret i1 %and
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:%.*]]
85   %ynot = xor i1 %y, -1
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
89   ret i1 %and
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
106   ret i1 %and
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
123   ret i1 %and
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
135   ret i1 %r
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>
147   ret <2 x i1>  %r
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>
159   ret <2 x i1>  %r
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>
171   ret <2 x i1>  %r
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
184   ret i1 %r
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
196   ret i1 %r
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
208   ret i1 %r
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
220   ret i1 %r
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>
232   ret <3 x i1> %r
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]], splat (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>
248   ret <3 x i1> %r
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>
260   ret <3 x i1> %r
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>
272   ret <3 x i1> %r
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]]
283   %or = or i1 %x, %y
284   %r = select i1 %or, i1 false, i1 %z
285   ret i1 %r
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
297   ret i1 %or
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> splat (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
307   ret <2 x i1> %or
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> splat (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
317   ret <2 x i1> %or
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
327   ret i1 %or
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]], splat (i1 true)
336 ; CHECK-NEXT:    [[OR:%.*]] = select <2 x i1> [[X]], <2 x i1> splat (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
342   ret <2 x i1> %or
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
357   ret i1 %or
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
366   %or = or i1 %x, %y
367   %r = select i1 %or, i1 false, i1 %x
368   ret i1 %r
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
377   %or = or i1 %x, %y
378   %r = select i1 %or, i1 false, i1 %y
379   ret i1 %r
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
390   ret <2 x i1> %r
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
401   ret <2 x i1> %r
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
412   ret i1 %r
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
423   ret i1 %r
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
434   ret <2 x i1> %r
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
448   ret <2 x i1> %r
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
459   ret <2 x i1> %r
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]]
470   %or = or i1 %x, %y
471   %r = select i1 %or, i1 false, i1 %z
472   ret i1 %r
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:%.*]]
481   %or = or i1 %x, %y
482   %r = select i1 %or, i1 %x, i1 %y
483   ret i1 %r
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:%.*]]
491   %or = or i1 %x, %y
492   %r = select i1 %or, i1 %y, i1 %x
493   ret i1 %r
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
503   ret <2 x i1> %r
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
513   ret i1 %r
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
523   ret i1 %r
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
533   ret <2 x i1> %r
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
547   ret <2 x i1> %r
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]]
558   %or = or i1 %x, %y
559   %r = select i1 %or, i1 %x, i1 %z
560   ret i1 %r
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:%.*]]
569   %a = and i1 %x, %y
570   %r = select i1 %a, i1 %x, i1 %y
571   ret i1 %r
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:%.*]]
579   %a = and i1 %x, %y
580   %r = select i1 %a, i1 %y, i1 %x
581   ret i1 %r
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
591   ret <2 x i1> %r
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
601   ret i1 %r
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
611   ret i1 %r
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
621   ret <2 x i1> %r
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
635   ret <2 x i1> %r
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]]
646   %a = and i1 %x, %y
647   %r = select i1 %a, i1 %x, i1 %z
648   ret i1 %r
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
656   ret i1 %r
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
664   ret <2 x i1> %r
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> splat (i1 true)
671   %r = select <2 x i1> %x, <2 x i1> %x, <2 x i1> <i1 poison, i1 true>
672   ret <2 x i1> %r
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
680   ret i1 %r
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
691   ret i1 %r
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
700   ret <2 x i1> %r
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
709   ret <2 x i1> %r
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> splat (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
722   ret <2 x i1> %r
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
731   ret <2 x i1> %r
734 ; negative test
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
744   ret i1 %r
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
755   ret i1 %r
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
764   ret <2 x i1> %r
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>
774   ret <2 x i1> %r
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
783   ret <2 x i1> %r
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
796   ret <2 x i1> %r
799 ; negative test
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
809   ret i1 %r