xref: /llvm-project/llvm/test/Transforms/InstSimplify/select-logical.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4define i1 @logical_and_of_or_commute0(i1 %x, i1 %y) {
5; CHECK-LABEL: @logical_and_of_or_commute0(
6; CHECK-NEXT:    ret i1 [[X:%.*]]
7;
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
13}
14
15define <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:%.*]]
18;
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
24}
25
26define i1 @logical_and_of_or_commute2(i1 %x, i1 %y) {
27; CHECK-LABEL: @logical_and_of_or_commute2(
28; CHECK-NEXT:    ret i1 [[X:%.*]]
29;
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
35}
36
37define i1 @logical_and_of_or_commute3(i1 %x, i1 %y) {
38; CHECK-LABEL: @logical_and_of_or_commute3(
39; CHECK-NEXT:    ret i1 [[X:%.*]]
40;
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
46}
47
48define i1 @logical_and_of_or_commute4(i1 %x, i1 %y) {
49; CHECK-LABEL: @logical_and_of_or_commute4(
50; CHECK-NEXT:    ret i1 [[X:%.*]]
51;
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
57}
58
59define i1 @logical_and_of_or_commute5(i1 %x, i1 %y) {
60; CHECK-LABEL: @logical_and_of_or_commute5(
61; CHECK-NEXT:    ret i1 [[X:%.*]]
62;
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
68}
69
70define i1 @logical_and_of_or_commute6(i1 %x, i1 %y) {
71; CHECK-LABEL: @logical_and_of_or_commute6(
72; CHECK-NEXT:    ret i1 [[X:%.*]]
73;
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
79}
80
81define i1 @logical_and_of_or_commute7(i1 %x, i1 %y) {
82; CHECK-LABEL: @logical_and_of_or_commute7(
83; CHECK-NEXT:    ret i1 [[X:%.*]]
84;
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
90}
91
92; negative test - wrong logic op
93
94define 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]]
101;
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
107}
108
109; negative test - must have common operands
110
111define 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]]
118;
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
124}
125
126; !(X | Y) && X --> false
127
128define i1 @or_not_and(i1 %x, i1 %y) {
129; CHECK-LABEL: @or_not_and(
130; CHECK-NEXT:    ret i1 false
131;
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
136}
137
138; vector case !(X | Y) && X --> false
139
140define <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
143;
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
148}
149
150; vector case !(X | Y) && X --> false
151
152define <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
155;
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
160}
161
162; vector case !(X | Y) && X --> false
163
164define <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
167;
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
172}
173
174
175; !(X || Y) && X --> false
176
177define i1 @logical_or_not_and(i1 %x, i1 %y) {
178; CHECK-LABEL: @logical_or_not_and(
179; CHECK-NEXT:    ret i1 false
180;
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
185}
186
187; !(X || Y) && Y --> false
188
189define 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
192;
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
197}
198
199; X && !(X || Y) --> false
200
201define i1 @logical_or_not_commute_and(i1 %x, i1 %y) {
202; CHECK-LABEL: @logical_or_not_commute_and(
203; CHECK-NEXT:    ret i1 false
204;
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
209}
210
211; Y && !(X || Y) --> false
212
213define 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
216;
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
221}
222
223; vector case !(X || Y) && X --> false
224
225define <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
228;
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
233}
234
235; TODO: this could transform to false
236; vector case !(X || Y) && X --> false
237
238define <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]]
244;
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
249}
250
251; vector case !(X || Y) && X --> false
252
253define <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
256;
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
261}
262
263; vector case !(X || Y) && X --> false
264
265define <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
268;
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
273}
274
275; negative test - must have common operands
276
277define 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]]
282;
283  %or = or i1 %x, %y
284  %r = select i1 %or, i1 false, i1 %z
285  ret i1 %r
286}
287
288; !(x && y) || x --> true
289
290define 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
293;
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
298}
299
300define <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)
303;
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
308}
309
310define <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)
313;
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
318}
319
320define 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
323;
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
328}
329
330; TODO: This could fold the same as above (we don't match a partial poison vector as logical op).
331
332define <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]]
338;
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
343}
344
345; negative test - need common operand
346
347define 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]]
353;
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
358}
359
360; (X | Y) ? false : X --> false
361
362define i1 @or_select_false_x_case1(i1 %x, i1 %y) {
363; CHECK-LABEL: @or_select_false_x_case1(
364; CHECK-NEXT:    ret i1 false
365;
366  %or = or i1 %x, %y
367  %r = select i1 %or, i1 false, i1 %x
368  ret i1 %r
369}
370
371; (X | Y) ? false : X --> false
372
373define i1 @or_select_false_x_case2(i1 %x, i1 %y) {
374; CHECK-LABEL: @or_select_false_x_case2(
375; CHECK-NEXT:    ret i1 false
376;
377  %or = or i1 %x, %y
378  %r = select i1 %or, i1 false, i1 %y
379  ret i1 %r
380}
381
382; vector case (X | Y) ? false : X --> false
383
384define <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
387;
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
391}
392
393; vector poison case (X | Y) ? false : X --> false
394
395define <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
398;
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
402}
403
404; (X || Y) ? false : X --> false
405
406define 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
409;
410  %or = select i1 %x, i1 true, i1 %y
411  %r = select i1 %or, i1 false, i1 %x
412  ret i1 %r
413}
414
415; (X || Y) ? false : X --> false
416
417define 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
420;
421  %or = select i1 %y, i1 true, i1 %x
422  %r = select i1 %or, i1 false, i1 %x
423  ret i1 %r
424}
425
426; vector case (X || Y) ? false : X --> false
427
428define <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
431;
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
435}
436
437; TODO: this could transform to false
438; vector poison case (X || Y) ? false : X --> false
439
440define <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]]
445;
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
449}
450
451; vector poison case (X || Y) ? false : X --> false
452
453define <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
456;
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
460}
461
462; negative test - must have common operands
463
464define 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]]
469;
470  %or = or i1 %x, %y
471  %r = select i1 %or, i1 false, i1 %z
472  ret i1 %r
473}
474
475; (X || Y) ? X : Y --> X
476
477define i1 @select_or_same_op(i1 %x, i1 %y) {
478; CHECK-LABEL: @select_or_same_op(
479; CHECK-NEXT:    ret i1 [[X:%.*]]
480;
481  %or = or i1 %x, %y
482  %r = select i1 %or, i1 %x, i1 %y
483  ret i1 %r
484}
485
486
487define i1 @select_or_same_op_commute(i1 %x, i1 %y) {
488; CHECK-LABEL: @select_or_same_op_commute(
489; CHECK-NEXT:    ret i1 [[Y:%.*]]
490;
491  %or = or i1 %x, %y
492  %r = select i1 %or, i1 %y, i1 %x
493  ret i1 %r
494}
495
496
497define <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:%.*]]
500;
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
504}
505
506
507define i1 @select_logic_or1_same_op(i1 %x, i1 %y) {
508; CHECK-LABEL: @select_logic_or1_same_op(
509; CHECK-NEXT:    ret i1 [[X:%.*]]
510;
511  %or = select i1 %x, i1 true, i1 %y
512  %r = select i1 %or, i1 %x, i1 %y
513  ret i1 %r
514}
515
516
517define i1 @select_logic_or2_same_op(i1 %x, i1 %y) {
518; CHECK-LABEL: @select_logic_or2_same_op(
519; CHECK-NEXT:    ret i1 [[X:%.*]]
520;
521  %or = select i1 %y, i1 true, i1 %x
522  %r = select i1 %or, i1 %x, i1 %y
523  ret i1 %r
524}
525
526
527define <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:%.*]]
530;
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
534}
535
536; TODO: this could transform to X
537; (X || Y) ? X : Y --> X
538
539define <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]]
544;
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
548}
549
550; negative test - must have common operands
551
552define 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]]
557;
558  %or = or i1 %x, %y
559  %r = select i1 %or, i1 %x, i1 %z
560  ret i1 %r
561}
562
563; (X && Y) ? X : Y --> Y
564
565define i1 @select_and_same_op(i1 %x, i1 %y) {
566; CHECK-LABEL: @select_and_same_op(
567; CHECK-NEXT:    ret i1 [[Y:%.*]]
568;
569  %a = and i1 %x, %y
570  %r = select i1 %a, i1 %x, i1 %y
571  ret i1 %r
572}
573
574
575define i1 @select_and_same_op_commute(i1 %x, i1 %y) {
576; CHECK-LABEL: @select_and_same_op_commute(
577; CHECK-NEXT:    ret i1 [[X:%.*]]
578;
579  %a = and i1 %x, %y
580  %r = select i1 %a, i1 %y, i1 %x
581  ret i1 %r
582}
583
584
585define <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:%.*]]
588;
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
592}
593
594
595define i1 @select_logic_and1_same_op(i1 %x, i1 %y) {
596; CHECK-LABEL: @select_logic_and1_same_op(
597; CHECK-NEXT:    ret i1 [[Y:%.*]]
598;
599  %a = select i1 %x, i1 %y, i1 false
600  %r = select i1 %a, i1 %x, i1 %y
601  ret i1 %r
602}
603
604
605define i1 @select_logic_and2_same_op(i1 %x, i1 %y) {
606; CHECK-LABEL: @select_logic_and2_same_op(
607; CHECK-NEXT:    ret i1 [[Y:%.*]]
608;
609  %a = select i1 %y, i1 %x, i1 false
610  %r = select i1 %a, i1 %x, i1 %y
611  ret i1 %r
612}
613
614
615define <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:%.*]]
618;
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
622}
623
624; TODO: this could transform to Y
625; (X && Y) ? X : Y --> Y
626
627define <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]]
632;
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
636}
637
638; negative test - must have common operands
639
640define 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]]
645;
646  %a = and i1 %x, %y
647  %r = select i1 %a, i1 %x, i1 %z
648  ret i1 %r
649}
650
651define i1 @and_same_op(i1 %x) {
652; CHECK-LABEL: @and_same_op(
653; CHECK-NEXT:    ret i1 [[X:%.*]]
654;
655  %r = select i1 %x, i1 %x, i1 false
656  ret i1 %r
657}
658
659define <2 x i1> @or_same_op(<2 x i1> %x) {
660; CHECK-LABEL: @or_same_op(
661; CHECK-NEXT:    ret <2 x i1> [[X:%.*]]
662;
663  %r = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %x
664  ret <2 x i1> %r
665}
666
667define <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)
670;
671  %r = select <2 x i1> %x, <2 x i1> %x, <2 x i1> <i1 poison, i1 true>
672  ret <2 x i1> %r
673}
674
675define i1 @always_false_same_op(i1 %x) {
676; CHECK-LABEL: @always_false_same_op(
677; CHECK-NEXT:    ret i1 false
678;
679  %r = select i1 %x, i1 false, i1 %x
680  ret i1 %r
681}
682
683; (X && Y) || Y --> Y
684
685define i1 @or_and_common_op_commute0(i1 %x, i1 %y) {
686; CHECK-LABEL: @or_and_common_op_commute0(
687; CHECK-NEXT:    ret i1 [[Y:%.*]]
688;
689  %a = select i1 %x, i1 %y, i1 false
690  %r = select i1 %a, i1 true, i1 %y
691  ret i1 %r
692}
693
694define <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:%.*]]
697;
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
701}
702
703define <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:%.*]]
706;
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
710}
711
712; TODO: this could fold the same as above
713
714define <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]]
719;
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
723}
724
725define <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:%.*]]
728;
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
732}
733
734; negative test
735
736define 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]]
741;
742  %a = select i1 %x, i1 %y, i1 false
743  %r = select i1 %a, i1 true, i1 %z
744  ret i1 %r
745}
746
747; (X || Y) && Y --> Y
748
749define i1 @and_or_common_op_commute0(i1 %x, i1 %y) {
750; CHECK-LABEL: @and_or_common_op_commute0(
751; CHECK-NEXT:    ret i1 [[Y:%.*]]
752;
753  %o = select i1 %x, i1 true, i1 %y
754  %r = select i1 %o, i1 %y, i1 false
755  ret i1 %r
756}
757
758define <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:%.*]]
761;
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
765}
766
767
768define <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:%.*]]
771;
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
775}
776
777define <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:%.*]]
780;
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
784}
785
786; TODO: this could fold the same as above
787
788define <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]]
793;
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
797}
798
799; negative test
800
801define 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]]
806;
807  %o = select i1 %x, i1 true, i1 %y
808  %r = select i1 %z, i1 %o, i1 false
809  ret i1 %r
810}
811