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