xref: /llvm-project/llvm/test/Transforms/InstCombine/select-and-or.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4declare void @use(i1)
5declare i1 @gen_i1()
6declare <2 x i1> @gen_v2i1()
7
8; Should not be converted to "and", which has different poison semantics.
9define i1 @logical_and(i1 %a, i1 %b) {
10; CHECK-LABEL: @logical_and(
11; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
12; CHECK-NEXT:    ret i1 [[RES]]
13;
14  %res = select i1 %a, i1 %b, i1 false
15  ret i1 %res
16}
17
18; Should not be converted to "or", which has different poison semantics.
19define i1 @logical_or(i1 %a, i1 %b) {
20; CHECK-LABEL: @logical_or(
21; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
22; CHECK-NEXT:    ret i1 [[RES]]
23;
24  %res = select i1 %a, i1 true, i1 %b
25  ret i1 %res
26}
27; Canonicalize to logical and form, even if that requires adding a "not".
28define i1 @logical_and_not(i1 %a, i1 %b) {
29; CHECK-LABEL: @logical_and_not(
30; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
31; CHECK-NEXT:    [[RES:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false
32; CHECK-NEXT:    ret i1 [[RES]]
33;
34  %res = select i1 %a, i1 false, i1 %b
35  ret i1 %res
36}
37
38; Canonicalize to logical or form, even if that requires adding a "not".
39define i1 @logical_or_not(i1 %a, i1 %b) {
40; CHECK-LABEL: @logical_or_not(
41; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
42; CHECK-NEXT:    [[RES:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]]
43; CHECK-NEXT:    ret i1 [[RES]]
44;
45  %res = select i1 %a, i1 %b, i1 true
46  ret i1 %res
47}
48
49; These are variants where condition or !condition is used to represent true
50; or false in one of the select arms. It should be canonicalized to the
51; constants.
52
53define i1 @logical_and_cond_reuse(i1 %a, i1 %b) {
54; CHECK-LABEL: @logical_and_cond_reuse(
55; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
56; CHECK-NEXT:    ret i1 [[RES]]
57;
58  %res = select i1 %a, i1 %b, i1 %a
59  ret i1 %res
60}
61
62define i1 @logical_or_cond_reuse(i1 %a, i1 %b) {
63; CHECK-LABEL: @logical_or_cond_reuse(
64; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
65; CHECK-NEXT:    ret i1 [[RES]]
66;
67  %res = select i1 %a, i1 %a, i1 %b
68  ret i1 %res
69}
70
71define i1 @logical_and_not_cond_reuse(i1 %a, i1 %b) {
72; CHECK-LABEL: @logical_and_not_cond_reuse(
73; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
74; CHECK-NEXT:    [[RES:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B:%.*]]
75; CHECK-NEXT:    ret i1 [[RES]]
76;
77  %a.not = xor i1 %a, true
78  %res = select i1 %a, i1 %b, i1 %a.not
79  ret i1 %res
80}
81
82define i1 @logical_or_not_cond_reuse(i1 %a, i1 %b) {
83; CHECK-LABEL: @logical_or_not_cond_reuse(
84; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
85; CHECK-NEXT:    [[RES:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false
86; CHECK-NEXT:    ret i1 [[RES]]
87;
88  %a.not = xor i1 %a, true
89  %res = select i1 %a, i1 %a.not, i1 %b
90  ret i1 %res
91}
92
93; Safe to convert to or due to poison implication.
94define i1 @logical_or_implies(i32 %x) {
95; CHECK-LABEL: @logical_or_implies(
96; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[X:%.*]], 0
97; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[X]], 42
98; CHECK-NEXT:    [[RES:%.*]] = or i1 [[C1]], [[C2]]
99; CHECK-NEXT:    ret i1 [[RES]]
100;
101  %c1 = icmp eq i32 %x, 0
102  %c2 = icmp eq i32 %x, 42
103  %res = select i1 %c1, i1 true, i1 %c2
104  ret i1 %res
105}
106
107; Will fold after conversion to or.
108define i1 @logical_or_implies_folds(i32 %x) {
109; CHECK-LABEL: @logical_or_implies_folds(
110; CHECK-NEXT:    ret i1 true
111;
112  %c1 = icmp slt i32 %x, 0
113  %c2 = icmp sge i32 %x, 0
114  %res = select i1 %c1, i1 true, i1 %c2
115  ret i1 %res
116}
117
118; Safe to convert to and due to poison implication.
119define i1 @logical_and_implies(i32 %x) {
120; CHECK-LABEL: @logical_and_implies(
121; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[X:%.*]], 0
122; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 [[X]], 42
123; CHECK-NEXT:    [[RES:%.*]] = and i1 [[C1]], [[C2]]
124; CHECK-NEXT:    ret i1 [[RES]]
125;
126  %c1 = icmp ne i32 %x, 0
127  %c2 = icmp ne i32 %x, 42
128  %res = select i1 %c1, i1 %c2, i1 false
129  ret i1 %res
130}
131
132; Will fold after conversion to and.
133define i1 @logical_and_implies_folds(i32 %x) {
134; CHECK-LABEL: @logical_and_implies_folds(
135; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i32 [[X:%.*]], 42
136; CHECK-NEXT:    ret i1 [[C1]]
137;
138  %c1 = icmp ugt i32 %x, 42
139  %c2 = icmp ne i32 %x, 0
140  %res = select i1 %c1, i1 %c2, i1 false
141  ret i1 %res
142}
143
144; Noundef on condition has no effect.
145define i1 @logical_or_noundef_a(i1 noundef %a, i1 %b) {
146; CHECK-LABEL: @logical_or_noundef_a(
147; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
148; CHECK-NEXT:    ret i1 [[RES]]
149;
150  %res = select i1 %a, i1 true, i1 %b
151  ret i1 %res
152}
153
154; Noundef on false value allows conversion to or.
155define i1 @logical_or_noundef_b(i1 %a, i1 noundef %b) {
156; CHECK-LABEL: @logical_or_noundef_b(
157; CHECK-NEXT:    [[RES:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
158; CHECK-NEXT:    ret i1 [[RES]]
159;
160  %res = select i1 %a, i1 true, i1 %b
161  ret i1 %res
162}
163
164; Noundef on condition has no effect.
165define i1 @logical_and_noundef_a(i1 noundef %a, i1 %b) {
166; CHECK-LABEL: @logical_and_noundef_a(
167; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
168; CHECK-NEXT:    ret i1 [[RES]]
169;
170  %res = select i1 %a, i1 %b, i1 false
171  ret i1 %res
172}
173
174; Noundef on false value allows conversion to and.
175define i1 @logical_and_noundef_b(i1 %a, i1 noundef %b) {
176; CHECK-LABEL: @logical_and_noundef_b(
177; CHECK-NEXT:    [[RES:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
178; CHECK-NEXT:    ret i1 [[RES]]
179;
180  %res = select i1 %a, i1 %b, i1 false
181  ret i1 %res
182}
183
184; (!x && !y) || x --> x || !y
185
186define i1 @not_not_true(i1 %x, i1 %y) {
187; CHECK-LABEL: @not_not_true(
188; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
189; CHECK-NEXT:    [[R:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[NOTY]]
190; CHECK-NEXT:    ret i1 [[R]]
191;
192  %notx = xor i1 %x, true
193  %noty = xor i1 %y, true
194  %r = select i1 %notx, i1 %noty, i1 true
195  ret i1 %r
196}
197
198; (!x && !y) --> !(x || y)
199
200define i1 @not_not_false(i1 %x, i1 %y) {
201; CHECK-LABEL: @not_not_false(
202; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
203; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
204; CHECK-NEXT:    ret i1 [[R]]
205;
206  %notx = xor i1 %x, true
207  %noty = xor i1 %y, true
208  %r = select i1 %notx, i1 %noty, i1 false
209  ret i1 %r
210}
211
212; (!x || !y) --> !(x && y)
213
214define i1 @not_true_not(i1 %x, i1 %y) {
215; CHECK-LABEL: @not_true_not(
216; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
217; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
218; CHECK-NEXT:    ret i1 [[R]]
219;
220  %notx = xor i1 %x, true
221  %noty = xor i1 %y, true
222  %r = select i1 %notx, i1 true, i1 %noty
223  ret i1 %r
224}
225
226; (!!x && !y) --> x && !y
227
228define i1 @not_false_not(i1 %x, i1 %y) {
229; CHECK-LABEL: @not_false_not(
230; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
231; CHECK-NEXT:    [[R:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
232; CHECK-NEXT:    ret i1 [[R]]
233;
234  %notx = xor i1 %x, true
235  %noty = xor i1 %y, true
236  %r = select i1 %notx, i1 false, i1 %noty
237  ret i1 %r
238}
239
240define i1 @not_not_true_use1(i1 %x, i1 %y) {
241; CHECK-LABEL: @not_not_true_use1(
242; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
243; CHECK-NEXT:    call void @use(i1 [[NOTX]])
244; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
245; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i1 true, i1 [[NOTY]]
246; CHECK-NEXT:    ret i1 [[R]]
247;
248  %notx = xor i1 %x, true
249  call void @use(i1 %notx)
250  %noty = xor i1 %y, true
251  %r = select i1 %notx, i1 %noty, i1 true
252  ret i1 %r
253}
254
255define i1 @not_not_false_use1(i1 %x, i1 %y) {
256; CHECK-LABEL: @not_not_false_use1(
257; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
258; CHECK-NEXT:    call void @use(i1 [[NOTX]])
259; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X]], i1 true, i1 [[Y:%.*]]
260; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
261; CHECK-NEXT:    ret i1 [[R]]
262;
263  %notx = xor i1 %x, true
264  call void @use(i1 %notx)
265  %noty = xor i1 %y, true
266  %r = select i1 %notx, i1 %noty, i1 false
267  ret i1 %r
268}
269
270define i1 @not_true_not_use1(i1 %x, i1 %y) {
271; CHECK-LABEL: @not_true_not_use1(
272; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
273; CHECK-NEXT:    call void @use(i1 [[NOTX]])
274; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false
275; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
276; CHECK-NEXT:    ret i1 [[R]]
277;
278  %notx = xor i1 %x, true
279  call void @use(i1 %notx)
280  %noty = xor i1 %y, true
281  %r = select i1 %notx, i1 true, i1 %noty
282  ret i1 %r
283}
284
285define i1 @not_false_not_use1(i1 %x, i1 %y) {
286; CHECK-LABEL: @not_false_not_use1(
287; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
288; CHECK-NEXT:    call void @use(i1 [[NOTX]])
289; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
290; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i1 [[NOTY]], i1 false
291; CHECK-NEXT:    ret i1 [[R]]
292;
293  %notx = xor i1 %x, true
294  call void @use(i1 %notx)
295  %noty = xor i1 %y, true
296  %r = select i1 %notx, i1 false, i1 %noty
297  ret i1 %r
298}
299
300define i1 @not_not_true_use2(i1 %x, i1 %y) {
301; CHECK-LABEL: @not_not_true_use2(
302; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
303; CHECK-NEXT:    call void @use(i1 [[NOTY]])
304; CHECK-NEXT:    [[R:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[NOTY]]
305; CHECK-NEXT:    ret i1 [[R]]
306;
307  %notx = xor i1 %x, true
308  %noty = xor i1 %y, true
309  call void @use(i1 %noty)
310  %r = select i1 %notx, i1 %noty, i1 true
311  ret i1 %r
312}
313
314define i1 @not_not_false_use2(i1 %x, i1 %y) {
315; CHECK-LABEL: @not_not_false_use2(
316; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
317; CHECK-NEXT:    call void @use(i1 [[NOTY]])
318; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y]]
319; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
320; CHECK-NEXT:    ret i1 [[R]]
321;
322  %notx = xor i1 %x, true
323  %noty = xor i1 %y, true
324  call void @use(i1 %noty)
325  %r = select i1 %notx, i1 %noty, i1 false
326  ret i1 %r
327}
328
329define i1 @not_true_not_use2(i1 %x, i1 %y) {
330; CHECK-LABEL: @not_true_not_use2(
331; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
332; CHECK-NEXT:    call void @use(i1 [[NOTY]])
333; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X:%.*]], i1 [[Y]], i1 false
334; CHECK-NEXT:    [[R:%.*]] = xor i1 [[TMP1]], true
335; CHECK-NEXT:    ret i1 [[R]]
336;
337  %notx = xor i1 %x, true
338  %noty = xor i1 %y, true
339  call void @use(i1 %noty)
340  %r = select i1 %notx, i1 true, i1 %noty
341  ret i1 %r
342}
343
344define i1 @not_false_not_use2(i1 %x, i1 %y) {
345; CHECK-LABEL: @not_false_not_use2(
346; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
347; CHECK-NEXT:    call void @use(i1 [[NOTY]])
348; CHECK-NEXT:    [[R:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
349; CHECK-NEXT:    ret i1 [[R]]
350;
351  %notx = xor i1 %x, true
352  %noty = xor i1 %y, true
353  call void @use(i1 %noty)
354  %r = select i1 %notx, i1 false, i1 %noty
355  ret i1 %r
356}
357
358define i1 @not_not_true_use3(i1 %x, i1 %y) {
359; CHECK-LABEL: @not_not_true_use3(
360; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
361; CHECK-NEXT:    call void @use(i1 [[NOTX]])
362; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
363; CHECK-NEXT:    call void @use(i1 [[NOTY]])
364; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i1 true, i1 [[NOTY]]
365; CHECK-NEXT:    ret i1 [[R]]
366;
367  %notx = xor i1 %x, true
368  call void @use(i1 %notx)
369  %noty = xor i1 %y, true
370  call void @use(i1 %noty)
371  %r = select i1 %notx, i1 %noty, i1 true
372  ret i1 %r
373}
374
375define i1 @not_not_false_use3(i1 %x, i1 %y) {
376; CHECK-LABEL: @not_not_false_use3(
377; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
378; CHECK-NEXT:    call void @use(i1 [[NOTX]])
379; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
380; CHECK-NEXT:    call void @use(i1 [[NOTY]])
381; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTX]], i1 [[NOTY]], i1 false
382; CHECK-NEXT:    ret i1 [[R]]
383;
384  %notx = xor i1 %x, true
385  call void @use(i1 %notx)
386  %noty = xor i1 %y, true
387  call void @use(i1 %noty)
388  %r = select i1 %notx, i1 %noty, i1 false
389  ret i1 %r
390}
391
392define i1 @not_true_not_use3(i1 %x, i1 %y) {
393; CHECK-LABEL: @not_true_not_use3(
394; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
395; CHECK-NEXT:    call void @use(i1 [[NOTX]])
396; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
397; CHECK-NEXT:    call void @use(i1 [[NOTY]])
398; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTX]], i1 true, i1 [[NOTY]]
399; CHECK-NEXT:    ret i1 [[R]]
400;
401  %notx = xor i1 %x, true
402  call void @use(i1 %notx)
403  %noty = xor i1 %y, true
404  call void @use(i1 %noty)
405  %r = select i1 %notx, i1 true, i1 %noty
406  ret i1 %r
407}
408
409define i1 @not_false_not_use3(i1 %x, i1 %y) {
410; CHECK-LABEL: @not_false_not_use3(
411; CHECK-NEXT:    [[NOTX:%.*]] = xor i1 [[X:%.*]], true
412; CHECK-NEXT:    call void @use(i1 [[NOTX]])
413; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
414; CHECK-NEXT:    call void @use(i1 [[NOTY]])
415; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i1 [[NOTY]], i1 false
416; CHECK-NEXT:    ret i1 [[R]]
417;
418  %notx = xor i1 %x, true
419  call void @use(i1 %notx)
420  %noty = xor i1 %y, true
421  call void @use(i1 %noty)
422  %r = select i1 %notx, i1 false, i1 %noty
423  ret i1 %r
424}
425
426; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35399
427
428@g1 = external global i16
429@g2 = external global i16
430
431define i1 @demorgan_select_infloop1(i1 %L) {
432; CHECK-LABEL: @demorgan_select_infloop1(
433; CHECK-NEXT:    [[NOT_L:%.*]] = xor i1 [[L:%.*]], true
434; CHECK-NEXT:    ret i1 [[NOT_L]]
435;
436  %not.L = xor i1 %L, true
437  %cmp = icmp eq ptr getelementptr inbounds (i16, ptr @g2, i64 1), @g1
438  %add = add i1 %cmp, %cmp
439  %xor = xor i1 %add, true
440  %C15 = select i1 %not.L, i1 %xor, i1 false
441  ret i1 %C15
442}
443
444
445define i1 @demorgan_select_infloop2(i1 %L) {
446; CHECK-LABEL: @demorgan_select_infloop2(
447; CHECK-NEXT:    [[NOT_L:%.*]] = xor i1 [[L:%.*]], true
448; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne ptr getelementptr inbounds nuw (i8, ptr @g2, i64 2), @g1
449; CHECK-NEXT:    [[C15:%.*]] = select i1 [[NOT_L]], i1 [[CMP2]], i1 false
450; CHECK-NEXT:    ret i1 [[C15]]
451;
452  %not.L = xor i1 %L, true
453  %cmp1 = icmp eq ptr getelementptr inbounds (i16, ptr @g1, i64 1), @g1
454  %cmp2 = icmp eq ptr getelementptr inbounds (i16, ptr @g2, i64 1), @g1
455  %add = add i1 %cmp1, %cmp2
456  %xor = xor i1 %add, true
457  %C15 = select i1 %not.L, i1 %xor, i1 false
458  ret i1 %C15
459}
460
461define i1 @and_or1(i1 %a, i1 %b, i1 %c) {
462; CHECK-LABEL: @and_or1(
463; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]]
464; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false
465; CHECK-NEXT:    ret i1 [[R]]
466;
467  %nota = xor i1 %a, true
468  %cond = or i1 %nota, %c
469  %r = select i1 %cond, i1 %a, i1 %b
470  ret i1 %r
471}
472
473define i1 @and_or2(i1 %a, i1 %b, i1 %c) {
474; CHECK-LABEL: @and_or2(
475; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]]
476; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false
477; CHECK-NEXT:    ret i1 [[R]]
478;
479  %notc = xor i1 %c, true
480  %cond = and i1 %notc, %b
481  %r = select i1 %cond, i1 %a, i1 %b
482  ret i1 %r
483}
484
485define i1 @and_or1_commuted(i1 %a, i1 %b, i1 %c) {
486; CHECK-LABEL: @and_or1_commuted(
487; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[B:%.*]]
488; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 [[TMP1]], i1 false
489; CHECK-NEXT:    ret i1 [[R]]
490;
491  %nota = xor i1 %a, true
492  %cond = or i1 %c, %nota
493  %r = select i1 %cond, i1 %a, i1 %b
494  ret i1 %r
495}
496
497define i1 @and_or2_commuted(i1 %a, i1 %b, i1 %c) {
498; CHECK-LABEL: @and_or2_commuted(
499; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]]
500; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP1]], i1 false
501; CHECK-NEXT:    ret i1 [[R]]
502;
503  %notc = xor i1 %c, true
504  %cond = and i1 %b, %notc
505  %r = select i1 %cond, i1 %a, i1 %b
506  ret i1 %r
507}
508
509define i1 @and_or1_multiuse(i1 %a, i1 %b, i1 %c) {
510; CHECK-LABEL: @and_or1_multiuse(
511; CHECK-NEXT:    [[NOTA:%.*]] = xor i1 [[A:%.*]], true
512; CHECK-NEXT:    [[COND:%.*]] = or i1 [[C:%.*]], [[NOTA]]
513; CHECK-NEXT:    call void @use(i1 [[COND]])
514; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]]
515; CHECK-NEXT:    ret i1 [[R]]
516;
517  %nota = xor i1 %a, true
518  %cond = or i1 %nota, %c
519  call void @use(i1 %cond)
520  %r = select i1 %cond, i1 %a, i1 %b
521  ret i1 %r
522}
523
524define i1 @and_or2_multiuse(i1 %a, i1 %b, i1 %c) {
525; CHECK-LABEL: @and_or2_multiuse(
526; CHECK-NEXT:    [[NOTC:%.*]] = xor i1 [[C:%.*]], true
527; CHECK-NEXT:    [[COND:%.*]] = and i1 [[B:%.*]], [[NOTC]]
528; CHECK-NEXT:    call void @use(i1 [[COND]])
529; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]]
530; CHECK-NEXT:    ret i1 [[R]]
531;
532  %notc = xor i1 %c, true
533  %cond = and i1 %notc, %b
534  call void @use(i1 %cond)
535  %r = select i1 %cond, i1 %a, i1 %b
536  ret i1 %r
537}
538
539define <2 x i1> @and_or1_vec(<2 x i1> %a, <2 x i1> %b) {
540; CHECK-LABEL: @and_or1_vec(
541; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
542; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
543; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
544; CHECK-NEXT:    ret <2 x i1> [[R]]
545;
546  %c = call <2 x i1> @gen_v2i1()
547  %nota = xor <2 x i1> %a, <i1 true, i1 true>
548  %cond = or <2 x i1> %nota, %c
549  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
550  ret <2 x i1> %r
551}
552
553define <2 x i1> @and_or2_vec(<2 x i1> %a, <2 x i1> %b) {
554; CHECK-LABEL: @and_or2_vec(
555; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
556; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]]
557; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
558; CHECK-NEXT:    ret <2 x i1> [[R]]
559;
560  %c = call <2 x i1> @gen_v2i1()
561  %notc = xor <2 x i1> %c, <i1 true, i1 true>
562  %cond = and <2 x i1> %notc, %b
563  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
564  ret <2 x i1> %r
565}
566
567define <2 x i1> @and_or1_vec_commuted(<2 x i1> %a, <2 x i1> %b) {
568; CHECK-LABEL: @and_or1_vec_commuted(
569; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
570; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[B:%.*]]
571; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
572; CHECK-NEXT:    ret <2 x i1> [[R]]
573;
574  %c = call <2 x i1> @gen_v2i1()
575  %nota = xor <2 x i1> %a, <i1 true, i1 true>
576  %cond = or <2 x i1> %c, %nota
577  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
578  ret <2 x i1> %r
579}
580
581define <2 x i1> @and_or2_vec_commuted(<2 x i1> %a, <2 x i1> %b) {
582; CHECK-LABEL: @and_or2_vec_commuted(
583; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
584; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]]
585; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
586; CHECK-NEXT:    ret <2 x i1> [[R]]
587;
588  %c = call <2 x i1> @gen_v2i1()
589  %notc = xor <2 x i1> %c, <i1 true, i1 true>
590  %cond = and <2 x i1> %b, %notc
591  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
592  ret <2 x i1> %r
593}
594
595define i1 @and_or1_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) {
596; CHECK-LABEL: @and_or1_wrong_operand(
597; CHECK-NEXT:    [[NOTA:%.*]] = xor i1 [[A:%.*]], true
598; CHECK-NEXT:    [[COND:%.*]] = or i1 [[C:%.*]], [[NOTA]]
599; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]]
600; CHECK-NEXT:    ret i1 [[R]]
601;
602  %nota = xor i1 %a, true
603  %cond = or i1 %nota, %c
604  %r = select i1 %cond, i1 %d, i1 %b
605  ret i1 %r
606}
607
608define i1 @and_or2_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) {
609; CHECK-LABEL: @and_or2_wrong_operand(
610; CHECK-NEXT:    [[NOTC:%.*]] = xor i1 [[C:%.*]], true
611; CHECK-NEXT:    [[COND:%.*]] = and i1 [[B:%.*]], [[NOTC]]
612; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]]
613; CHECK-NEXT:    ret i1 [[R]]
614;
615  %notc = xor i1 %c, true
616  %cond = and i1 %notc, %b
617  %r = select i1 %cond, i1 %a, i1 %d
618  ret i1 %r
619}
620
621define i1 @and_or3(i1 %a, i1 %b, i32 %x, i32 %y) {
622; CHECK-LABEL: @and_or3(
623; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
624; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[A:%.*]]
625; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP2]], i1 false
626; CHECK-NEXT:    ret i1 [[R]]
627;
628  %c = icmp eq i32 %x, %y
629  %cond = and i1 %b, %c
630  %r = select i1 %cond, i1 %a, i1 %b
631  ret i1 %r
632}
633
634define i1 @and_or3_commuted(i1 %a, i1 %b, i32 %x, i32 %y) {
635; CHECK-LABEL: @and_or3_commuted(
636; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
637; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[A:%.*]]
638; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 [[TMP2]], i1 false
639; CHECK-NEXT:    ret i1 [[R]]
640;
641  %c = icmp eq i32 %x, %y
642  %cond = and i1 %c, %b
643  %r = select i1 %cond, i1 %a, i1 %b
644  ret i1 %r
645}
646
647define i1 @and_or3_not_free_to_invert(i1 %a, i1 %b, i1 %c) {
648; CHECK-LABEL: @and_or3_not_free_to_invert(
649; CHECK-NEXT:    [[COND:%.*]] = and i1 [[B:%.*]], [[C:%.*]]
650; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]]
651; CHECK-NEXT:    ret i1 [[R]]
652;
653  %cond = and i1 %b, %c
654  %r = select i1 %cond, i1 %a, i1 %b
655  ret i1 %r
656}
657
658define i1 @and_or3_multiuse(i1 %a, i1 %b, i32 %x, i32 %y) {
659; CHECK-LABEL: @and_or3_multiuse(
660; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
661; CHECK-NEXT:    [[COND:%.*]] = and i1 [[B:%.*]], [[C]]
662; CHECK-NEXT:    call void @use(i1 [[COND]])
663; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]]
664; CHECK-NEXT:    ret i1 [[R]]
665;
666  %c = icmp eq i32 %x, %y
667  %cond = and i1 %b, %c
668  call void @use(i1 %cond)
669  %r = select i1 %cond, i1 %a, i1 %b
670  ret i1 %r
671}
672
673define <2 x i1> @and_or3_vec(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) {
674; CHECK-LABEL: @and_or3_vec(
675; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
676; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]]
677; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP2]], <2 x i1> zeroinitializer
678; CHECK-NEXT:    ret <2 x i1> [[R]]
679;
680  %c = icmp eq <2 x i32> %x, %y
681  %cond = and <2 x i1> %b, %c
682  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
683  ret <2 x i1> %r
684}
685
686define <2 x i1> @and_or3_vec_commuted(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) {
687; CHECK-LABEL: @and_or3_vec_commuted(
688; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
689; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> splat (i1 true), <2 x i1> [[A:%.*]]
690; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> [[TMP2]], <2 x i1> zeroinitializer
691; CHECK-NEXT:    ret <2 x i1> [[R]]
692;
693  %c = icmp eq <2 x i32> %x, %y
694  %cond = and <2 x i1> %c, %b
695  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
696  ret <2 x i1> %r
697}
698
699define i1 @and_or3_wrong_operand(i1 %a, i1 %b, i32 %x, i32 %y, i1 %d) {
700; CHECK-LABEL: @and_or3_wrong_operand(
701; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
702; CHECK-NEXT:    [[COND:%.*]] = and i1 [[B:%.*]], [[C]]
703; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]]
704; CHECK-NEXT:    ret i1 [[R]]
705;
706  %c = icmp eq i32 %x, %y
707  %cond = and i1 %b, %c
708  %r = select i1 %cond, i1 %a, i1 %d
709  ret i1 %r
710}
711
712define i1 @or_and1(i1 %a, i1 %b, i1 %c) {
713; CHECK-LABEL: @or_and1(
714; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false
715; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[TMP1]]
716; CHECK-NEXT:    ret i1 [[R]]
717;
718  %notb = xor i1 %b, true
719  %cond = and i1 %notb, %c
720  %r = select i1 %cond, i1 %a, i1 %b
721  ret i1 %r
722}
723
724define i1 @or_and2(i1 %a, i1 %b, i1 %c) {
725; CHECK-LABEL: @or_and2(
726; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 false
727; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP1]]
728; CHECK-NEXT:    ret i1 [[R]]
729;
730  %notc = xor i1 %c, true
731  %cond = or i1 %notc, %a
732  %r = select i1 %cond, i1 %a, i1 %b
733  ret i1 %r
734}
735
736define i1 @or_and1_commuted(i1 %a, i1 %b, i1 %c) {
737; CHECK-LABEL: @or_and1_commuted(
738; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false
739; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[TMP1]]
740; CHECK-NEXT:    ret i1 [[R]]
741;
742  %notb = xor i1 %b, true
743  %cond = and i1 %c, %notb
744  %r = select i1 %cond, i1 %a, i1 %b
745  ret i1 %r
746}
747
748define i1 @or_and2_commuted(i1 %a, i1 %b, i1 %c) {
749; CHECK-LABEL: @or_and2_commuted(
750; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 false
751; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP1]]
752; CHECK-NEXT:    ret i1 [[R]]
753;
754  %notc = xor i1 %c, true
755  %cond = or i1 %a, %notc
756  %r = select i1 %cond, i1 %a, i1 %b
757  ret i1 %r
758}
759
760define i1 @or_and1_multiuse(i1 %a, i1 %b, i1 %c) {
761; CHECK-LABEL: @or_and1_multiuse(
762; CHECK-NEXT:    [[NOTB:%.*]] = xor i1 [[B:%.*]], true
763; CHECK-NEXT:    [[COND:%.*]] = and i1 [[C:%.*]], [[NOTB]]
764; CHECK-NEXT:    call void @use(i1 [[COND]])
765; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[B]]
766; CHECK-NEXT:    ret i1 [[R]]
767;
768  %notb = xor i1 %b, true
769  %cond = and i1 %notb, %c
770  call void @use(i1 %cond)
771  %r = select i1 %cond, i1 %a, i1 %b
772  ret i1 %r
773}
774
775define i1 @or_and2_multiuse(i1 %a, i1 %b, i1 %c) {
776; CHECK-LABEL: @or_and2_multiuse(
777; CHECK-NEXT:    [[NOTC:%.*]] = xor i1 [[C:%.*]], true
778; CHECK-NEXT:    [[COND:%.*]] = or i1 [[A:%.*]], [[NOTC]]
779; CHECK-NEXT:    call void @use(i1 [[COND]])
780; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]]
781; CHECK-NEXT:    ret i1 [[R]]
782;
783  %notc = xor i1 %c, true
784  %cond = or i1 %notc, %a
785  call void @use(i1 %cond)
786  %r = select i1 %cond, i1 %a, i1 %b
787  ret i1 %r
788}
789
790define <2 x i1> @or_and1_vec(<2 x i1> %a, <2 x i1> %b) {
791; CHECK-LABEL: @or_and1_vec(
792; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
793; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer
794; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]]
795; CHECK-NEXT:    ret <2 x i1> [[R]]
796;
797  %c = call <2 x i1> @gen_v2i1()
798  %notb = xor <2 x i1> %b, <i1 true, i1 true>
799  %cond = and <2 x i1> %c, %notb
800  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
801  ret <2 x i1> %r
802}
803
804define <2 x i1> @or_and2_vec(<2 x i1> %a, <2 x i1> %b) {
805; CHECK-LABEL: @or_and2_vec(
806; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
807; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
808; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]]
809; CHECK-NEXT:    ret <2 x i1> [[R]]
810;
811  %c = call <2 x i1> @gen_v2i1()
812  %notc = xor <2 x i1> %c, <i1 true, i1 true>
813  %cond = or <2 x i1> %a, %notc
814  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
815  ret <2 x i1> %r
816}
817
818define <2 x i1> @or_and1_vec_commuted(<2 x i1> %a, <2 x i1> %b) {
819; CHECK-LABEL: @or_and1_vec_commuted(
820; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
821; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[A:%.*]], <2 x i1> zeroinitializer
822; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]]
823; CHECK-NEXT:    ret <2 x i1> [[R]]
824;
825  %c = call <2 x i1> @gen_v2i1()
826  %notb = xor <2 x i1> %b, <i1 true, i1 true>
827  %cond = and <2 x i1> %notb, %c
828  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
829  ret <2 x i1> %r
830}
831
832define <2 x i1> @or_and2_vec_commuted(<2 x i1> %a, <2 x i1> %b) {
833; CHECK-LABEL: @or_and2_vec_commuted(
834; CHECK-NEXT:    [[C:%.*]] = call <2 x i1> @gen_v2i1()
835; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[C]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
836; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP1]]
837; CHECK-NEXT:    ret <2 x i1> [[R]]
838;
839  %c = call <2 x i1> @gen_v2i1()
840  %notc = xor <2 x i1> %c, <i1 true, i1 true>
841  %cond = or <2 x i1> %notc, %a
842  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
843  ret <2 x i1> %r
844}
845
846define i1 @or_and1_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) {
847; CHECK-LABEL: @or_and1_wrong_operand(
848; CHECK-NEXT:    [[NOTB:%.*]] = xor i1 [[B:%.*]], true
849; CHECK-NEXT:    [[COND:%.*]] = and i1 [[C:%.*]], [[NOTB]]
850; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A:%.*]], i1 [[D:%.*]]
851; CHECK-NEXT:    ret i1 [[R]]
852;
853  %notb = xor i1 %b, true
854  %cond = and i1 %c, %notb
855  %r = select i1 %cond, i1 %a, i1 %d
856  ret i1 %r
857}
858
859define i1 @or_and2_wrong_operand(i1 %a, i1 %b, i1 %c, i1 %d) {
860; CHECK-LABEL: @or_and2_wrong_operand(
861; CHECK-NEXT:    [[NOTC:%.*]] = xor i1 [[C:%.*]], true
862; CHECK-NEXT:    [[COND:%.*]] = or i1 [[A:%.*]], [[NOTC]]
863; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]]
864; CHECK-NEXT:    ret i1 [[R]]
865;
866  %notc = xor i1 %c, true
867  %cond = or i1 %a, %notc
868  %r = select i1 %cond, i1 %d, i1 %b
869  ret i1 %r
870}
871
872define i1 @pr64558(i1 noundef %a, i1 noundef %b) {
873; CHECK-LABEL: @pr64558(
874; CHECK-NEXT:  entry:
875; CHECK-NEXT:    [[COND_V:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
876; CHECK-NEXT:    ret i1 [[COND_V]]
877;
878entry:
879  %lnot = xor i1 %b, true
880  %and11 = and i1 %lnot, %a
881  %cond.v = select i1 %and11, i1 %a, i1 %b
882  ret i1 %cond.v
883}
884
885define i1 @or_and3(i1 %a, i1 %b, i32 %x, i32 %y) {
886; CHECK-LABEL: @or_and3(
887; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
888; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 false
889; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP2]]
890; CHECK-NEXT:    ret i1 [[R]]
891;
892  %c = icmp eq i32 %x, %y
893  %cond = or i1 %a, %c
894  %r = select i1 %cond, i1 %a, i1 %b
895  ret i1 %r
896}
897
898define i1 @or_and3_commuted(i1 %a, i1 %b, i32 %x, i32 %y) {
899; CHECK-LABEL: @or_and3_commuted(
900; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
901; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 false
902; CHECK-NEXT:    [[R:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[TMP2]]
903; CHECK-NEXT:    ret i1 [[R]]
904;
905  %c = icmp eq i32 %x, %y
906  %cond = or i1 %c, %a
907  %r = select i1 %cond, i1 %a, i1 %b
908  ret i1 %r
909}
910
911define i1 @or_and3_not_free_to_invert(i1 %a, i1 %b, i1 %c) {
912; CHECK-LABEL: @or_and3_not_free_to_invert(
913; CHECK-NEXT:    [[COND:%.*]] = or i1 [[A:%.*]], [[C:%.*]]
914; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]]
915; CHECK-NEXT:    ret i1 [[R]]
916;
917  %cond = or i1 %a, %c
918  %r = select i1 %cond, i1 %a, i1 %b
919  ret i1 %r
920}
921
922define i1 @or_and3_multiuse(i1 %a, i1 %b, i32 %x, i32 %y) {
923; CHECK-LABEL: @or_and3_multiuse(
924; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
925; CHECK-NEXT:    [[COND:%.*]] = or i1 [[A:%.*]], [[C]]
926; CHECK-NEXT:    call void @use(i1 [[COND]])
927; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[A]], i1 [[B:%.*]]
928; CHECK-NEXT:    ret i1 [[R]]
929;
930  %c = icmp eq i32 %x, %y
931  %cond = or i1 %a, %c
932  call void @use(i1 %cond)
933  %r = select i1 %cond, i1 %a, i1 %b
934  ret i1 %r
935}
936
937define <2 x i1> @or_and3_vec(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) {
938; CHECK-LABEL: @or_and3_vec(
939; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
940; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
941; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP2]]
942; CHECK-NEXT:    ret <2 x i1> [[R]]
943;
944  %c = icmp eq <2 x i32> %x, %y
945  %cond = or <2 x i1> %a, %c
946  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
947  ret <2 x i1> %r
948}
949
950define <2 x i1> @or_and3_vec_commuted(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) {
951; CHECK-LABEL: @or_and3_vec_commuted(
952; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
953; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer
954; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[TMP2]]
955; CHECK-NEXT:    ret <2 x i1> [[R]]
956;
957  %c = icmp eq <2 x i32> %x, %y
958  %cond = or <2 x i1> %c, %a
959  %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b
960  ret <2 x i1> %r
961}
962
963define i1 @or_and3_wrong_operand(i1 %a, i1 %b, i32 %x, i32 %y, i1 %d) {
964; CHECK-LABEL: @or_and3_wrong_operand(
965; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
966; CHECK-NEXT:    [[COND:%.*]] = or i1 [[A:%.*]], [[C]]
967; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND]], i1 [[D:%.*]], i1 [[B:%.*]]
968; CHECK-NEXT:    ret i1 [[R]]
969;
970  %c = icmp eq i32 %x, %y
971  %cond = or i1 %a, %c
972  %r = select i1 %cond, i1 %d, i1 %b
973  ret i1 %r
974}
975
976define i8 @test_or_umax(i8 %x, i8 %y, i1 %cond) {
977; CHECK-LABEL: @test_or_umax(
978; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
979; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]]
980; CHECK-NEXT:    ret i8 [[RET]]
981;
982  %cmp = icmp ugt i8 %x, %y
983  %or = select i1 %cond, i1 true, i1 %cmp
984  %ret = select i1 %or, i8 %x, i8 %y
985  ret i8 %ret
986}
987
988define i8 @test_or_umin(i8 %x, i8 %y, i1 %cond) {
989; CHECK-LABEL: @test_or_umin(
990; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
991; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[Y]], i8 [[TMP1]]
992; CHECK-NEXT:    ret i8 [[RET]]
993;
994  %cmp = icmp ugt i8 %x, %y
995  %or = select i1 %cond, i1 true, i1 %cmp
996  %ret = select i1 %or, i8 %y, i8 %x
997  ret i8 %ret
998}
999
1000define i8 @test_and_umax(i8 %x, i8 %y, i1 %cond) {
1001; CHECK-LABEL: @test_and_umax(
1002; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1003; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[TMP1]], i8 [[Y]]
1004; CHECK-NEXT:    ret i8 [[RET]]
1005;
1006  %cmp = icmp ugt i8 %x, %y
1007  %and = select i1 %cond, i1 %cmp, i1 false
1008  %ret = select i1 %and, i8 %x, i8 %y
1009  ret i8 %ret
1010}
1011
1012define i8 @test_and_umin(i8 %x, i8 %y, i1 %cond) {
1013; CHECK-LABEL: @test_and_umin(
1014; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1015; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[TMP1]], i8 [[X]]
1016; CHECK-NEXT:    ret i8 [[RET]]
1017;
1018  %cmp = icmp ugt i8 %x, %y
1019  %and = select i1 %cond, i1 %cmp, i1 false
1020  %ret = select i1 %and, i8 %y, i8 %x
1021  ret i8 %ret
1022}
1023
1024define i8 @test_or_umax_bitwise1(i8 %x, i8 %y, i8 %val) {
1025; CHECK-LABEL: @test_or_umax_bitwise1(
1026; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0
1027; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1028; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND]], i8 [[X]], i8 [[TMP1]]
1029; CHECK-NEXT:    ret i8 [[RET]]
1030;
1031  %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering
1032  %cmp = icmp ugt i8 %x, %y
1033  %or = or i1 %cond, %cmp
1034  %ret = select i1 %or, i8 %x, i8 %y
1035  ret i8 %ret
1036}
1037
1038define i8 @test_or_umax_bitwise2(i8 %x, i8 %y, i8 %val) {
1039; CHECK-LABEL: @test_or_umax_bitwise2(
1040; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0
1041; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1042; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND]], i8 [[X]], i8 [[TMP1]]
1043; CHECK-NEXT:    ret i8 [[RET]]
1044;
1045  %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering
1046  %cmp = icmp ugt i8 %x, %y
1047  %or = or i1 %cmp, %cond
1048  %ret = select i1 %or, i8 %x, i8 %y
1049  ret i8 %ret
1050}
1051
1052define i8 @test_and_umax_bitwise1(i8 %x, i8 %y, i8 %val) {
1053; CHECK-LABEL: @test_and_umax_bitwise1(
1054; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0
1055; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1056; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND]], i8 [[TMP1]], i8 [[Y]]
1057; CHECK-NEXT:    ret i8 [[RET]]
1058;
1059  %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering
1060  %cmp = icmp ugt i8 %x, %y
1061  %and = and i1 %cond, %cmp
1062  %ret = select i1 %and, i8 %x, i8 %y
1063  ret i8 %ret
1064}
1065
1066define i8 @test_and_umax_bitwise2(i8 %x, i8 %y, i8 %val) {
1067; CHECK-LABEL: @test_and_umax_bitwise2(
1068; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[VAL:%.*]], 0
1069; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1070; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND]], i8 [[TMP1]], i8 [[Y]]
1071; CHECK-NEXT:    ret i8 [[RET]]
1072;
1073  %cond = icmp eq i8 %val, 0 ; thwart complexity-based ordering
1074  %cmp = icmp ugt i8 %x, %y
1075  %and = and i1 %cmp, %cond
1076  %ret = select i1 %and, i8 %x, i8 %y
1077  ret i8 %ret
1078}
1079
1080; Other SPFs
1081
1082define i8 @test_or_smax(i8 %x, i8 %y, i1 %cond) {
1083; CHECK-LABEL: @test_or_smax(
1084; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
1085; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]]
1086; CHECK-NEXT:    ret i8 [[RET]]
1087;
1088  %cmp = icmp sgt i8 %x, %y
1089  %or = select i1 %cond, i1 true, i1 %cmp
1090  %ret = select i1 %or, i8 %x, i8 %y
1091  ret i8 %ret
1092}
1093
1094define i8 @test_or_abs(i8 %x, i1 %cond) {
1095; CHECK-LABEL: @test_or_abs(
1096; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)
1097; CHECK-NEXT:    [[RET:%.*]] = select i1 [[COND:%.*]], i8 [[X]], i8 [[TMP1]]
1098; CHECK-NEXT:    ret i8 [[RET]]
1099;
1100  %cmp = icmp sgt i8 %x, -1
1101  %neg = sub nsw i8 0, %x
1102  %or = select i1 %cond, i1 true, i1 %cmp
1103  %ret = select i1 %or, i8 %x, i8 %neg
1104  ret i8 %ret
1105}
1106
1107; TODO: fold SPF_FMAXNUM
1108define float @test_or_fmaxnum(float %x, float %y, i1 %cond) {
1109; CHECK-LABEL: @test_or_fmaxnum(
1110; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
1111; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]]
1112; CHECK-NEXT:    [[RET:%.*]] = select i1 [[OR]], float [[X]], float [[Y]]
1113; CHECK-NEXT:    ret float [[RET]]
1114;
1115  %cmp = fcmp nnan ogt float %x, %y
1116  %or = select i1 %cond, i1 true, i1 %cmp
1117  %ret = select i1 %or, float %x, float %y
1118  ret float %ret
1119}
1120
1121; Negative tests
1122
1123define i8 @test_or_umax_invalid_logical(i8 %x, i8 %y, i1 %cond) {
1124; CHECK-LABEL: @test_or_umax_invalid_logical(
1125; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
1126; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP]], i1 true, i1 [[COND:%.*]]
1127; CHECK-NEXT:    [[RET:%.*]] = select i1 [[OR]], i8 [[X]], i8 [[Y]]
1128; CHECK-NEXT:    ret i8 [[RET]]
1129;
1130  %cmp = icmp ugt i8 %x, %y
1131  %or = select i1 %cmp, i1 true, i1 %cond
1132  %ret = select i1 %or, i8 %x, i8 %y
1133  ret i8 %ret
1134}
1135
1136define i8 @test_and_umax_invalid_logical(i8 %x, i8 %y, i1 %cond) {
1137; CHECK-LABEL: @test_and_umax_invalid_logical(
1138; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
1139; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP]], i1 [[COND:%.*]], i1 false
1140; CHECK-NEXT:    [[RET:%.*]] = select i1 [[AND]], i8 [[X]], i8 [[Y]]
1141; CHECK-NEXT:    ret i8 [[RET]]
1142;
1143  %cmp = icmp ugt i8 %x, %y
1144  %and = select i1 %cmp, i1 %cond, i1 false
1145  %ret = select i1 %and, i8 %x, i8 %y
1146  ret i8 %ret
1147}
1148
1149define i8 @test_or_umax_multiuse_cond(i8 %x, i8 %y, i1 %cond) {
1150; CHECK-LABEL: @test_or_umax_multiuse_cond(
1151; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
1152; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]]
1153; CHECK-NEXT:    call void @use(i1 [[OR]])
1154; CHECK-NEXT:    [[RET:%.*]] = select i1 [[OR]], i8 [[X]], i8 [[Y]]
1155; CHECK-NEXT:    ret i8 [[RET]]
1156;
1157  %cmp = icmp ugt i8 %x, %y
1158  %or = select i1 %cond, i1 true, i1 %cmp
1159  call void @use(i1 %or)
1160  %ret = select i1 %or, i8 %x, i8 %y
1161  ret i8 %ret
1162}
1163
1164; Tests from PR76203
1165
1166define i8 @test_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1167; CHECK-LABEL: @test_or_eq_a_b(
1168; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
1169; CHECK-NEXT:    ret i8 [[SELECT]]
1170;
1171  %cmp = icmp eq i8 %a, %b
1172  %cond = or i1 %other_cond, %cmp
1173  %select = select i1 %cond, i8 %a, i8 %b
1174  ret i8 %select
1175}
1176
1177define i8 @test_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1178; CHECK-LABEL: @test_and_ne_a_b(
1179; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
1180; CHECK-NEXT:    ret i8 [[SELECT]]
1181;
1182  %cmp = icmp ne i8 %a, %b
1183  %cond = and i1 %other_cond, %cmp
1184  %select = select i1 %cond, i8 %a, i8 %b
1185  ret i8 %select
1186}
1187
1188define i8 @test_or_eq_a_b_commuted(i1 %other_cond, i8 %a, i8 %b)  {
1189; CHECK-LABEL: @test_or_eq_a_b_commuted(
1190; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[B:%.*]], i8 [[A:%.*]]
1191; CHECK-NEXT:    ret i8 [[SELECT]]
1192;
1193  %cmp = icmp eq i8 %a, %b
1194  %cond = or i1 %other_cond, %cmp
1195  %select = select i1 %cond, i8 %b, i8 %a
1196  ret i8 %select
1197}
1198
1199define i8 @test_and_ne_a_b_commuted(i1 %other_cond, i8 %a, i8 %b)  {
1200; CHECK-LABEL: @test_and_ne_a_b_commuted(
1201; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[B:%.*]], i8 [[A:%.*]]
1202; CHECK-NEXT:    ret i8 [[SELECT]]
1203;
1204  %cmp = icmp ne i8 %a, %b
1205  %cond = and i1 %other_cond, %cmp
1206  %select = select i1 %cond, i8 %b, i8 %a
1207  ret i8 %select
1208}
1209
1210define i8 @test_or_eq_different_operands(i8 %a, i8 %b, i8 %c)  {
1211; CHECK-LABEL: @test_or_eq_different_operands(
1212; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[C:%.*]]
1213; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], i8 [[A]], i8 [[B:%.*]]
1214; CHECK-NEXT:    ret i8 [[SELECT]]
1215;
1216  %cmp = icmp eq i8 %a, %c
1217  %cmp1 = icmp eq i8 %b, %a
1218  %cond = or i1 %cmp, %cmp1
1219  %select = select i1 %cond, i8 %a, i8 %b
1220  ret i8 %select
1221}
1222
1223define i8 @test_or_eq_a_b_multi_use(i1 %other_cond, i8 %a, i8 %b)  {
1224; CHECK-LABEL: @test_or_eq_a_b_multi_use(
1225; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]]
1226; CHECK-NEXT:    [[COND:%.*]] = or i1 [[OTHER_COND:%.*]], [[CMP]]
1227; CHECK-NEXT:    call void @use(i1 [[CMP]])
1228; CHECK-NEXT:    call void @use(i1 [[COND]])
1229; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND]], i8 [[A]], i8 [[B]]
1230; CHECK-NEXT:    ret i8 [[SELECT]]
1231;
1232  %cmp = icmp eq i8 %a, %b
1233  %cond = or i1 %other_cond, %cmp
1234  call void @use(i1 %cmp)
1235  call void @use(i1 %cond)
1236  %select = select i1 %cond, i8 %a, i8 %b
1237  ret i8 %select
1238}
1239
1240define <2 x i8> @test_or_eq_a_b_vec(<2 x i1> %other_cond, <2 x i8> %a, <2 x i8> %b)  {
1241; CHECK-LABEL: @test_or_eq_a_b_vec(
1242; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[OTHER_COND:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]
1243; CHECK-NEXT:    ret <2 x i8> [[SELECT]]
1244;
1245  %cmp = icmp eq <2 x i8> %a, %b
1246  %cond = or <2 x i1> %other_cond, %cmp
1247  %select = select <2 x i1> %cond, <2 x i8> %a, <2 x i8> %b
1248  ret <2 x i8> %select
1249}
1250
1251define i8 @test_or_ne_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1252; CHECK-LABEL: @test_or_ne_a_b(
1253; CHECK-NEXT:    ret i8 [[A:%.*]]
1254;
1255  %cmp = icmp ne i8 %a, %b
1256  %cond = or i1 %other_cond, %cmp
1257  %select = select i1 %cond, i8 %a, i8 %b
1258  ret i8 %select
1259}
1260
1261define i8 @test_and_ne_different_operands_fail(i8 %a, i8 %b, i8 %c)  {
1262; CHECK-LABEL: @test_and_ne_different_operands_fail(
1263; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], [[C:%.*]]
1264; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[B:%.*]], [[C]]
1265; CHECK-NEXT:    [[COND:%.*]] = and i1 [[CMP]], [[CMP1]]
1266; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i8 [[B]], i8 [[A]]
1267; CHECK-NEXT:    ret i8 [[SELECT]]
1268;
1269  %cmp = icmp ne i8 %a, %c
1270  %cmp1 = icmp ne i8 %b, %c
1271  %cond = and i1 %cmp, %cmp1
1272  %select = select i1 %cond, i8 %b, i8 %a
1273  ret i8 %select
1274}
1275
1276define i8 @test_logical_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1277; CHECK-LABEL: @test_logical_or_eq_a_b(
1278; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
1279; CHECK-NEXT:    ret i8 [[SELECT]]
1280;
1281  %cmp = icmp eq i8 %a, %b
1282  %or.cond = select i1 %other_cond, i1 true, i1 %cmp
1283  %select = select i1 %or.cond, i8 %a, i8 %b
1284  ret i8 %select
1285}
1286
1287define i8 @test_logical_commuted_or_eq_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1288; CHECK-LABEL: @test_logical_commuted_or_eq_a_b(
1289; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]]
1290; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[OTHER_COND:%.*]]
1291; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OR_COND]], i8 [[A]], i8 [[B]]
1292; CHECK-NEXT:    ret i8 [[SELECT]]
1293;
1294  %cmp = icmp eq i8 %a, %b
1295  %or.cond = select i1 %cmp, i1 true, i1 %other_cond
1296  %select = select i1 %or.cond, i8 %a, i8 %b
1297  ret i8 %select
1298}
1299
1300define i8 @test_logical_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1301; CHECK-LABEL: @test_logical_and_ne_a_b(
1302; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OTHER_COND:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
1303; CHECK-NEXT:    ret i8 [[SELECT]]
1304;
1305  %cmp = icmp ne i8 %a, %b
1306  %or.cond = select i1 %other_cond, i1 %cmp, i1 false
1307  %select = select i1 %or.cond, i8 %a, i8 %b
1308  ret i8 %select
1309}
1310
1311define i8 @test_logical_commuted_and_ne_a_b(i1 %other_cond, i8 %a, i8 %b)  {
1312; CHECK-LABEL: @test_logical_commuted_and_ne_a_b(
1313; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]]
1314; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[OTHER_COND:%.*]], i1 false
1315; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[OR_COND]], i8 [[A]], i8 [[B]]
1316; CHECK-NEXT:    ret i8 [[SELECT]]
1317;
1318  %cmp = icmp ne i8 %a, %b
1319  %or.cond = select i1 %cmp, i1 %other_cond, i1 false
1320  %select = select i1 %or.cond, i8 %a, i8 %b
1321  ret i8 %select
1322}
1323