1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
6 declare <2 x i1> @gen_v2i1()
8 ; Should not be converted to "and", which has different poison semantics.
9 define 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]]
14 %res = select i1 %a, i1 %b, i1 false
18 ; Should not be converted to "or", which has different poison semantics.
19 define 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]]
24 %res = select i1 %a, i1 true, i1 %b
27 ; Canonicalize to logical and form, even if that requires adding a "not".
28 define 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]]
34 %res = select i1 %a, i1 false, i1 %b
38 ; Canonicalize to logical or form, even if that requires adding a "not".
39 define 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]]
45 %res = select i1 %a, i1 %b, i1 true
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
53 define 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]]
58 %res = select i1 %a, i1 %b, i1 %a
62 define 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]]
67 %res = select i1 %a, i1 %a, i1 %b
71 define 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]]
77 %a.not = xor i1 %a, true
78 %res = select i1 %a, i1 %b, i1 %a.not
82 define 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]]
88 %a.not = xor i1 %a, true
89 %res = select i1 %a, i1 %a.not, i1 %b
93 ; Safe to convert to or due to poison implication.
94 define 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]]
101 %c1 = icmp eq i32 %x, 0
102 %c2 = icmp eq i32 %x, 42
103 %res = select i1 %c1, i1 true, i1 %c2
107 ; Will fold after conversion to or.
108 define i1 @logical_or_implies_folds(i32 %x) {
109 ; CHECK-LABEL: @logical_or_implies_folds(
110 ; CHECK-NEXT: ret i1 true
112 %c1 = icmp slt i32 %x, 0
113 %c2 = icmp sge i32 %x, 0
114 %res = select i1 %c1, i1 true, i1 %c2
118 ; Safe to convert to and due to poison implication.
119 define 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]]
126 %c1 = icmp ne i32 %x, 0
127 %c2 = icmp ne i32 %x, 42
128 %res = select i1 %c1, i1 %c2, i1 false
132 ; Will fold after conversion to and.
133 define 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]]
138 %c1 = icmp ugt i32 %x, 42
139 %c2 = icmp ne i32 %x, 0
140 %res = select i1 %c1, i1 %c2, i1 false
144 ; Noundef on condition has no effect.
145 define 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]]
150 %res = select i1 %a, i1 true, i1 %b
154 ; Noundef on false value allows conversion to or.
155 define 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]]
160 %res = select i1 %a, i1 true, i1 %b
164 ; Noundef on condition has no effect.
165 define 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]]
170 %res = select i1 %a, i1 %b, i1 false
174 ; Noundef on false value allows conversion to and.
175 define 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]]
180 %res = select i1 %a, i1 %b, i1 false
184 ; (!x && !y) || x --> x || !y
186 define 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]]
192 %notx = xor i1 %x, true
193 %noty = xor i1 %y, true
194 %r = select i1 %notx, i1 %noty, i1 true
198 ; (!x && !y) --> !(x || y)
200 define 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]]
206 %notx = xor i1 %x, true
207 %noty = xor i1 %y, true
208 %r = select i1 %notx, i1 %noty, i1 false
212 ; (!x || !y) --> !(x && y)
214 define 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]]
220 %notx = xor i1 %x, true
221 %noty = xor i1 %y, true
222 %r = select i1 %notx, i1 true, i1 %noty
226 ; (!!x && !y) --> x && !y
228 define 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]]
234 %notx = xor i1 %x, true
235 %noty = xor i1 %y, true
236 %r = select i1 %notx, i1 false, i1 %noty
240 define 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]]
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
255 define 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]]
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
270 define 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]]
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
285 define 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]]
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
300 define 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]]
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
314 define 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]]
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
329 define 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]]
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
344 define 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]]
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
358 define 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]]
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
375 define 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]]
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
392 define 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]]
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
409 define 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]]
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
426 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35399
428 @g1 = external global i16
429 @g2 = external global i16
431 define 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]]
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
445 define 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]]
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
461 define 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]]
467 %nota = xor i1 %a, true
468 %cond = or i1 %nota, %c
469 %r = select i1 %cond, i1 %a, i1 %b
473 define 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]]
479 %notc = xor i1 %c, true
480 %cond = and i1 %notc, %b
481 %r = select i1 %cond, i1 %a, i1 %b
485 define 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]]
491 %nota = xor i1 %a, true
492 %cond = or i1 %c, %nota
493 %r = select i1 %cond, i1 %a, i1 %b
497 define 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]]
503 %notc = xor i1 %c, true
504 %cond = and i1 %b, %notc
505 %r = select i1 %cond, i1 %a, i1 %b
509 define 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]]
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
524 define 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]]
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
539 define <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]]
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
553 define <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]]
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
567 define <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]]
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
581 define <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]]
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
595 define 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]]
602 %nota = xor i1 %a, true
603 %cond = or i1 %nota, %c
604 %r = select i1 %cond, i1 %d, i1 %b
608 define 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]]
615 %notc = xor i1 %c, true
616 %cond = and i1 %notc, %b
617 %r = select i1 %cond, i1 %a, i1 %d
621 define 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]]
628 %c = icmp eq i32 %x, %y
629 %cond = and i1 %b, %c
630 %r = select i1 %cond, i1 %a, i1 %b
634 define 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]]
641 %c = icmp eq i32 %x, %y
642 %cond = and i1 %c, %b
643 %r = select i1 %cond, i1 %a, i1 %b
647 define 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]]
653 %cond = and i1 %b, %c
654 %r = select i1 %cond, i1 %a, i1 %b
658 define 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]]
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
673 define <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]]
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
686 define <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]]
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
699 define 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]]
706 %c = icmp eq i32 %x, %y
707 %cond = and i1 %b, %c
708 %r = select i1 %cond, i1 %a, i1 %d
712 define 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]]
718 %notb = xor i1 %b, true
719 %cond = and i1 %notb, %c
720 %r = select i1 %cond, i1 %a, i1 %b
724 define 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]]
730 %notc = xor i1 %c, true
731 %cond = or i1 %notc, %a
732 %r = select i1 %cond, i1 %a, i1 %b
736 define 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]]
742 %notb = xor i1 %b, true
743 %cond = and i1 %c, %notb
744 %r = select i1 %cond, i1 %a, i1 %b
748 define 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]]
754 %notc = xor i1 %c, true
755 %cond = or i1 %a, %notc
756 %r = select i1 %cond, i1 %a, i1 %b
760 define 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]]
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
775 define 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]]
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
790 define <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]]
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
804 define <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]]
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
818 define <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]]
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
832 define <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]]
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
846 define 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]]
853 %notb = xor i1 %b, true
854 %cond = and i1 %c, %notb
855 %r = select i1 %cond, i1 %a, i1 %d
859 define 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]]
866 %notc = xor i1 %c, true
867 %cond = or i1 %a, %notc
868 %r = select i1 %cond, i1 %d, i1 %b
872 define i1 @pr64558(i1 noundef %a, i1 noundef %b) {
873 ; CHECK-LABEL: @pr64558(
875 ; CHECK-NEXT: [[COND_V:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
876 ; CHECK-NEXT: ret i1 [[COND_V]]
879 %lnot = xor i1 %b, true
880 %and11 = and i1 %lnot, %a
881 %cond.v = select i1 %and11, i1 %a, i1 %b
885 define 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]]
892 %c = icmp eq i32 %x, %y
894 %r = select i1 %cond, i1 %a, i1 %b
898 define 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]]
905 %c = icmp eq i32 %x, %y
907 %r = select i1 %cond, i1 %a, i1 %b
911 define 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]]
918 %r = select i1 %cond, i1 %a, i1 %b
922 define 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]]
930 %c = icmp eq i32 %x, %y
932 call void @use(i1 %cond)
933 %r = select i1 %cond, i1 %a, i1 %b
937 define <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]]
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
950 define <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]]
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
963 define 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]]
970 %c = icmp eq i32 %x, %y
972 %r = select i1 %cond, i1 %d, i1 %b
976 define 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]]
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
988 define 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]]
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
1000 define 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]]
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
1012 define 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]]
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
1024 define 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]]
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
1038 define 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]]
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
1052 define 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]]
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
1066 define 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]]
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
1082 define 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]]
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
1094 define 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]]
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
1107 ; TODO: fold SPF_FMAXNUM
1108 define 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]]
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
1123 define 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]]
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
1136 define 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]]
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
1149 define 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]]
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
1164 ; Tests from PR76203
1166 define 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]]
1171 %cmp = icmp eq i8 %a, %b
1172 %cond = or i1 %other_cond, %cmp
1173 %select = select i1 %cond, i8 %a, i8 %b
1177 define 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]]
1182 %cmp = icmp ne i8 %a, %b
1183 %cond = and i1 %other_cond, %cmp
1184 %select = select i1 %cond, i8 %a, i8 %b
1188 define 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]]
1193 %cmp = icmp eq i8 %a, %b
1194 %cond = or i1 %other_cond, %cmp
1195 %select = select i1 %cond, i8 %b, i8 %a
1199 define 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]]
1204 %cmp = icmp ne i8 %a, %b
1205 %cond = and i1 %other_cond, %cmp
1206 %select = select i1 %cond, i8 %b, i8 %a
1210 define 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]]
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
1223 define 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]]
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
1240 define <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]]
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
1251 define 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:%.*]]
1255 %cmp = icmp ne i8 %a, %b
1256 %cond = or i1 %other_cond, %cmp
1257 %select = select i1 %cond, i8 %a, i8 %b
1261 define 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]]
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
1276 define 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]]
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
1287 define 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]]
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
1300 define 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]]
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
1311 define 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]]
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