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