1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; TODO: All of these should be optimized to less than or equal to a single
5; instruction of select/and/or.
6
7; --- (A op B) op' A   /   (B op A) op' A ---
8
9; (A land B) land A
10define i1 @land_land_left1(i1 %A, i1 %B) {
11; CHECK-LABEL: @land_land_left1(
12; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
13; CHECK-NEXT:    ret i1 [[C]]
14;
15  %c = select i1 %A, i1 %B, i1 false
16  %res = select i1 %c, i1 %A, i1 false
17  ret i1 %res
18}
19define i1 @land_land_left2(i1 %A, i1 %B) {
20; CHECK-LABEL: @land_land_left2(
21; CHECK-NEXT:    [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
22; CHECK-NEXT:    ret i1 [[RES]]
23;
24  %c = select i1 %B, i1 %A, i1 false
25  %res = select i1 %c, i1 %A, i1 false
26  ret i1 %res
27}
28
29; (A land B) band A
30define i1 @land_band_left1(i1 %A, i1 %B) {
31; CHECK-LABEL: @land_band_left1(
32; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
33; CHECK-NEXT:    ret i1 [[C]]
34;
35  %c = select i1 %A, i1 %B, i1 false
36  %res = and i1 %c, %A
37  ret i1 %res
38}
39define i1 @land_band_left2(i1 %A, i1 %B) {
40; CHECK-LABEL: @land_band_left2(
41; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
42; CHECK-NEXT:    ret i1 [[C]]
43;
44  %c = select i1 %B, i1 %A, i1 false
45  %res = and i1 %c, %A
46  ret i1 %res
47}
48
49; (A land B) lor A
50define i1 @land_lor_left1(i1 %A, i1 %B) {
51; CHECK-LABEL: @land_lor_left1(
52; CHECK-NEXT:    ret i1 [[A:%.*]]
53;
54  %c = select i1 %A, i1 %B, i1 false
55  %res = select i1 %c, i1 true, i1 %A
56  ret i1 %res
57}
58define i1 @land_lor_left2(i1 %A, i1 %B) {
59; CHECK-LABEL: @land_lor_left2(
60; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
61; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i1 true, i1 [[A]]
62; CHECK-NEXT:    ret i1 [[RES]]
63;
64  %c = select i1 %B, i1 %A, i1 false
65  %res = select i1 %c, i1 true, i1 %A
66  ret i1 %res
67}
68
69; (A land B) bor A
70define i1 @land_bor_left1(i1 %A, i1 %B) {
71; CHECK-LABEL: @land_bor_left1(
72; CHECK-NEXT:    ret i1 [[A:%.*]]
73;
74  %c = select i1 %A, i1 %B, i1 false
75  %res = or i1 %c, %A
76  ret i1 %res
77}
78define i1 @land_bor_left2(i1 %A, i1 %B) {
79; CHECK-LABEL: @land_bor_left2(
80; CHECK-NEXT:    ret i1 [[A:%.*]]
81;
82  %c = select i1 %B, i1 %A, i1 false
83  %res = or i1 %c, %A
84  ret i1 %res
85}
86
87; (A band B) land A
88define i1 @band_land_left1(i1 %A, i1 %B) {
89; CHECK-LABEL: @band_land_left1(
90; CHECK-NEXT:    [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
91; CHECK-NEXT:    ret i1 [[C]]
92;
93  %c = and i1 %A, %B
94  %res = select i1 %c, i1 %A, i1 false
95  ret i1 %res
96}
97define i1 @band_land_left2(i1 %A, i1 %B) {
98; CHECK-LABEL: @band_land_left2(
99; CHECK-NEXT:    [[C:%.*]] = and i1 [[B:%.*]], [[A:%.*]]
100; CHECK-NEXT:    ret i1 [[C]]
101;
102  %c = and i1 %B, %A
103  %res = select i1 %c, i1 %A, i1 false
104  ret i1 %res
105}
106
107; (A band B) lor A
108define i1 @band_lor_left1(i1 %A, i1 %B) {
109; CHECK-LABEL: @band_lor_left1(
110; CHECK-NEXT:    ret i1 [[A:%.*]]
111;
112  %c = and i1 %A, %B
113  %res = select i1 %c, i1 true, i1 %A
114  ret i1 %res
115}
116define i1 @band_lor_left2(i1 %A, i1 %B) {
117; CHECK-LABEL: @band_lor_left2(
118; CHECK-NEXT:    ret i1 [[A:%.*]]
119;
120  %c = and i1 %B, %A
121  %res = select i1 %c, i1 true, i1 %A
122  ret i1 %res
123}
124
125; (A lor B) land A
126define i1 @lor_land_left1(i1 %A, i1 %B) {
127; CHECK-LABEL: @lor_land_left1(
128; CHECK-NEXT:    ret i1 [[A:%.*]]
129;
130  %c = select i1 %A, i1 true, i1 %B
131  %res = select i1 %c, i1 %A, i1 false
132  ret i1 %res
133}
134define i1 @lor_land_left2(i1 %A, i1 %B) {
135; CHECK-LABEL: @lor_land_left2(
136; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
137; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i1 [[A]], i1 false
138; CHECK-NEXT:    ret i1 [[RES]]
139;
140  %c = select i1 %B, i1 true, i1 %A
141  %res = select i1 %c, i1 %A, i1 false
142  ret i1 %res
143}
144
145; (A lor B) band A
146define i1 @lor_band_left1(i1 %A, i1 %B) {
147; CHECK-LABEL: @lor_band_left1(
148; CHECK-NEXT:    ret i1 [[A:%.*]]
149;
150  %c = select i1 %A, i1 true, i1 %B
151  %res = and i1 %c, %A
152  ret i1 %res
153}
154define i1 @lor_band_left2(i1 %A, i1 %B) {
155; CHECK-LABEL: @lor_band_left2(
156; CHECK-NEXT:    ret i1 [[A:%.*]]
157;
158  %c = select i1 %B, i1 true, i1 %A
159  %res = and i1 %c, %A
160  ret i1 %res
161}
162
163; (A lor B) lor A
164define i1 @lor_lor_left1(i1 %A, i1 %B) {
165; CHECK-LABEL: @lor_lor_left1(
166; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
167; CHECK-NEXT:    ret i1 [[C]]
168;
169  %c = select i1 %A, i1 true, i1 %B
170  %res = select i1 %c, i1 true, i1 %A
171  ret i1 %res
172}
173define i1 @lor_lor_left2(i1 %A, i1 %B) {
174; CHECK-LABEL: @lor_lor_left2(
175; CHECK-NEXT:    [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
176; CHECK-NEXT:    ret i1 [[RES]]
177;
178  %c = select i1 %B, i1 true, i1 %A
179  %res = select i1 %c, i1 true, i1 %A
180  ret i1 %res
181}
182
183; (A lor B) bor A
184define i1 @lor_bor_left1(i1 %A, i1 %B) {
185; CHECK-LABEL: @lor_bor_left1(
186; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
187; CHECK-NEXT:    ret i1 [[C]]
188;
189  %c = select i1 %A, i1 true, i1 %B
190  %res = or i1 %c, %A
191  ret i1 %res
192}
193define i1 @lor_bor_left2(i1 %A, i1 %B) {
194; CHECK-LABEL: @lor_bor_left2(
195; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
196; CHECK-NEXT:    ret i1 [[C]]
197;
198  %c = select i1 %B, i1 true, i1 %A
199  %res = or i1 %c, %A
200  ret i1 %res
201}
202
203; (A bor B) land A
204define i1 @bor_land_left1(i1 %A, i1 %B) {
205; CHECK-LABEL: @bor_land_left1(
206; CHECK-NEXT:    ret i1 [[A:%.*]]
207;
208  %c = or i1 %A, %B
209  %res = select i1 %c, i1 %A, i1 false
210  ret i1 %res
211}
212define i1 @bor_land_left2(i1 %A, i1 %B) {
213; CHECK-LABEL: @bor_land_left2(
214; CHECK-NEXT:    ret i1 [[A:%.*]]
215;
216  %c = or i1 %B, %A
217  %res = select i1 %c, i1 %A, i1 false
218  ret i1 %res
219}
220
221; (A bor B) lor A
222define i1 @bor_lor_left1(i1 %A, i1 %B) {
223; CHECK-LABEL: @bor_lor_left1(
224; CHECK-NEXT:    [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
225; CHECK-NEXT:    ret i1 [[C]]
226;
227  %c = or i1 %A, %B
228  %res = select i1 %c, i1 true, i1 %A
229  ret i1 %res
230}
231define i1 @bor_lor_left2(i1 %A, i1 %B) {
232; CHECK-LABEL: @bor_lor_left2(
233; CHECK-NEXT:    [[C:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
234; CHECK-NEXT:    ret i1 [[C]]
235;
236  %c = or i1 %B, %A
237  %res = select i1 %c, i1 true, i1 %A
238  ret i1 %res
239}
240
241; --- A op (A op' B)   /   A op (B op' A) ---
242
243; A land (A land B)
244define i1 @land_land_right1(i1 %A, i1 %B) {
245; CHECK-LABEL: @land_land_right1(
246; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
247; CHECK-NEXT:    ret i1 [[RES]]
248;
249  %c = select i1 %A, i1 %B, i1 false
250  %res = select i1 %A, i1 %c, i1 false
251  ret i1 %res
252}
253define i1 @land_land_right2(i1 %A, i1 %B) {
254; CHECK-LABEL: @land_land_right2(
255; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
256; CHECK-NEXT:    ret i1 [[RES]]
257;
258  %c = select i1 %B, i1 %A, i1 false
259  %res = select i1 %A, i1 %c, i1 false
260  ret i1 %res
261}
262
263; A band (A land B)
264define i1 @land_band_right1(i1 %A, i1 %B) {
265; CHECK-LABEL: @land_band_right1(
266; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
267; CHECK-NEXT:    ret i1 [[C]]
268;
269  %c = select i1 %A, i1 %B, i1 false
270  %res = and i1 %A, %c
271  ret i1 %res
272}
273define i1 @land_band_right2(i1 %A, i1 %B) {
274; CHECK-LABEL: @land_band_right2(
275; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
276; CHECK-NEXT:    ret i1 [[C]]
277;
278  %c = select i1 %B, i1 %A, i1 false
279  %res = and i1 %A, %c
280  ret i1 %res
281}
282
283; A lor (A land B)
284define i1 @land_lor_right1(i1 %A, i1 %B) {
285; CHECK-LABEL: @land_lor_right1(
286; CHECK-NEXT:    ret i1 [[A:%.*]]
287;
288  %c = select i1 %A, i1 %B, i1 false
289  %res = select i1 %A, i1 true, i1 %c
290  ret i1 %res
291}
292define i1 @land_lor_right2(i1 %A, i1 %B) {
293; CHECK-LABEL: @land_lor_right2(
294; CHECK-NEXT:    ret i1 [[A:%.*]]
295;
296  %c = select i1 %B, i1 %A, i1 false
297  %res = select i1 %A, i1 true, i1 %c
298  ret i1 %res
299}
300
301; A bor (A land B)
302define i1 @land_bor_right1(i1 %A, i1 %B) {
303; CHECK-LABEL: @land_bor_right1(
304; CHECK-NEXT:    ret i1 [[A:%.*]]
305;
306  %c = select i1 %A, i1 %B, i1 false
307  %res = or i1 %A, %c
308  ret i1 %res
309}
310define i1 @land_bor_right2(i1 %A, i1 %B) {
311; CHECK-LABEL: @land_bor_right2(
312; CHECK-NEXT:    ret i1 [[A:%.*]]
313;
314  %c = select i1 %B, i1 %A, i1 false
315  %res = or i1 %A, %c
316  ret i1 %res
317}
318
319; A land (A band B)
320define i1 @band_land_right1(i1 %A, i1 %B) {
321; CHECK-LABEL: @band_land_right1(
322; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
323; CHECK-NEXT:    ret i1 [[RES]]
324;
325  %c = and i1 %A, %B
326  %res = select i1 %A, i1 %c, i1 false
327  ret i1 %res
328}
329define i1 @band_land_right2(i1 %A, i1 %B) {
330; CHECK-LABEL: @band_land_right2(
331; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
332; CHECK-NEXT:    ret i1 [[RES]]
333;
334  %c = and i1 %B, %A
335  %res = select i1 %A, i1 %c, i1 false
336  ret i1 %res
337}
338
339; A lor (A band B)
340define i1 @band_lor_right1(i1 %A, i1 %B) {
341; CHECK-LABEL: @band_lor_right1(
342; CHECK-NEXT:    ret i1 [[A:%.*]]
343;
344  %c = and i1 %A, %B
345  %res = select i1 %A, i1 true, i1 %c
346  ret i1 %res
347}
348define i1 @band_lor_right2(i1 %A, i1 %B) {
349; CHECK-LABEL: @band_lor_right2(
350; CHECK-NEXT:    ret i1 [[A:%.*]]
351;
352  %c = and i1 %B, %A
353  %res = select i1 %A, i1 true, i1 %c
354  ret i1 %res
355}
356
357; A land (A lor B)
358define i1 @lor_land_right1(i1 %A, i1 %B) {
359; CHECK-LABEL: @lor_land_right1(
360; CHECK-NEXT:    ret i1 [[A:%.*]]
361;
362  %c = select i1 %A, i1 true, i1 %B
363  %res = select i1 %A, i1 %c, i1 false
364  ret i1 %res
365}
366define i1 @lor_land_right2(i1 %A, i1 %B) {
367; CHECK-LABEL: @lor_land_right2(
368; CHECK-NEXT:    ret i1 [[A:%.*]]
369;
370  %c = select i1 %B, i1 true, i1 %A
371  %res = select i1 %A, i1 %c, i1 false
372  ret i1 %res
373}
374
375; A band (A lor B)
376define i1 @lor_band_right1(i1 %A, i1 %B) {
377; CHECK-LABEL: @lor_band_right1(
378; CHECK-NEXT:    ret i1 [[A:%.*]]
379;
380  %c = select i1 %A, i1 true, i1 %B
381  %res = and i1 %A, %c
382  ret i1 %res
383}
384define i1 @lor_band_right2(i1 %A, i1 %B) {
385; CHECK-LABEL: @lor_band_right2(
386; CHECK-NEXT:    ret i1 [[A:%.*]]
387;
388  %c = select i1 %B, i1 true, i1 %A
389  %res = and i1 %A, %c
390  ret i1 %res
391}
392
393; A lor (A lor B)
394define i1 @lor_lor_right1(i1 %A, i1 %B) {
395; CHECK-LABEL: @lor_lor_right1(
396; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
397; CHECK-NEXT:    ret i1 [[RES]]
398;
399  %c = select i1 %A, i1 true, i1 %B
400  %res = select i1 %A, i1 true, i1 %c
401  ret i1 %res
402}
403define i1 @lor_lor_right2(i1 %A, i1 %B) {
404; CHECK-LABEL: @lor_lor_right2(
405; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
406; CHECK-NEXT:    ret i1 [[RES]]
407;
408  %c = select i1 %B, i1 true, i1 %A
409  %res = select i1 %A, i1 true, i1 %c
410  ret i1 %res
411}
412
413; A bor (A lor B)
414define i1 @lor_bor_right1(i1 %A, i1 %B) {
415; CHECK-LABEL: @lor_bor_right1(
416; CHECK-NEXT:    [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
417; CHECK-NEXT:    ret i1 [[C]]
418;
419  %c = select i1 %A, i1 true, i1 %B
420  %res = or i1 %A, %c
421  ret i1 %res
422}
423define i1 @lor_bor_right2(i1 %A, i1 %B) {
424; CHECK-LABEL: @lor_bor_right2(
425; CHECK-NEXT:    [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
426; CHECK-NEXT:    ret i1 [[C]]
427;
428  %c = select i1 %B, i1 true, i1 %A
429  %res = or i1 %A, %c
430  ret i1 %res
431}
432
433; A land (A bor B)
434define i1 @bor_land_right1(i1 %A, i1 %B) {
435; CHECK-LABEL: @bor_land_right1(
436; CHECK-NEXT:    ret i1 [[A:%.*]]
437;
438  %c = or i1 %A, %B
439  %res = select i1 %A, i1 %c, i1 false
440  ret i1 %res
441}
442define i1 @bor_land_right2(i1 %A, i1 %B) {
443; CHECK-LABEL: @bor_land_right2(
444; CHECK-NEXT:    ret i1 [[A:%.*]]
445;
446  %c = or i1 %B, %A
447  %res = select i1 %A, i1 %c, i1 false
448  ret i1 %res
449}
450
451; A lor (A bor B)
452define i1 @bor_lor_right1(i1 %A, i1 %B) {
453; CHECK-LABEL: @bor_lor_right1(
454; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
455; CHECK-NEXT:    ret i1 [[RES]]
456;
457  %c = or i1 %A, %B
458  %res = select i1 %A, i1 true, i1 %c
459  ret i1 %res
460}
461define i1 @bor_lor_right2(i1 %A, i1 %B) {
462; CHECK-LABEL: @bor_lor_right2(
463; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
464; CHECK-NEXT:    ret i1 [[RES]]
465;
466  %c = or i1 %B, %A
467  %res = select i1 %A, i1 true, i1 %c
468  ret i1 %res
469}
470
471; Value equivalence substitution does not account for vector
472; transforms, so it needs a scalar condition operand.
473; For example, this would miscompile if %a = {1, 0}.
474
475define <2 x i1> @PR50500_trueval(<2 x i1> %a, <2 x i1> %b) {
476; CHECK-LABEL: @PR50500_trueval(
477; CHECK-NEXT:    [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
478; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[S]], <2 x i1> [[B:%.*]]
479; CHECK-NEXT:    ret <2 x i1> [[R]]
480;
481  %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
482  %r = select <2 x i1> %a, <2 x i1> %s, <2 x i1> %b
483  ret <2 x i1> %r
484}
485
486define <2 x i1> @PR50500_falseval(<2 x i1> %a, <2 x i1> %b) {
487; CHECK-LABEL: @PR50500_falseval(
488; CHECK-NEXT:    [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
489; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B:%.*]], <2 x i1> [[S]]
490; CHECK-NEXT:    ret <2 x i1> [[R]]
491;
492  %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
493  %r = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %s
494  ret <2 x i1> %r
495}
496