1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; TODO: All of these should be optimized to less than or equal to a single
5 ; instruction of select/and/or.
7 ; --- (A op B) op' A / (B op A) op' A ---
10 define i1 @land_land_left1(i1 %A, i1 %B) {
11 ; CHECK-LABEL: @land_land_left1(
12 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
13 ; CHECK-NEXT: ret i1 [[C]]
15 %c = select i1 %A, i1 %B, i1 false
16 %res = select i1 %c, i1 %A, i1 false
19 define i1 @land_land_left2(i1 %A, i1 %B) {
20 ; CHECK-LABEL: @land_land_left2(
21 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
22 ; CHECK-NEXT: ret i1 [[RES]]
24 %c = select i1 %B, i1 %A, i1 false
25 %res = select i1 %c, i1 %A, i1 false
30 define i1 @land_band_left1(i1 %A, i1 %B) {
31 ; CHECK-LABEL: @land_band_left1(
32 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
33 ; CHECK-NEXT: ret i1 [[C]]
35 %c = select i1 %A, i1 %B, i1 false
39 define i1 @land_band_left2(i1 %A, i1 %B) {
40 ; CHECK-LABEL: @land_band_left2(
41 ; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
42 ; CHECK-NEXT: ret i1 [[C]]
44 %c = select i1 %B, i1 %A, i1 false
50 define i1 @land_lor_left1(i1 %A, i1 %B) {
51 ; CHECK-LABEL: @land_lor_left1(
52 ; CHECK-NEXT: ret i1 [[A:%.*]]
54 %c = select i1 %A, i1 %B, i1 false
55 %res = select i1 %c, i1 true, i1 %A
58 define i1 @land_lor_left2(i1 %A, i1 %B) {
59 ; CHECK-LABEL: @land_lor_left2(
60 ; CHECK-NEXT: ret i1 [[A:%.*]]
62 %c = select i1 %B, i1 %A, i1 false
63 %res = select i1 %c, i1 true, i1 %A
68 define i1 @land_bor_left1(i1 %A, i1 %B) {
69 ; CHECK-LABEL: @land_bor_left1(
70 ; CHECK-NEXT: ret i1 [[A:%.*]]
72 %c = select i1 %A, i1 %B, i1 false
76 define i1 @land_bor_left2(i1 %A, i1 %B) {
77 ; CHECK-LABEL: @land_bor_left2(
78 ; CHECK-NEXT: ret i1 [[A:%.*]]
80 %c = select i1 %B, i1 %A, i1 false
86 define i1 @band_land_left1(i1 %A, i1 %B) {
87 ; CHECK-LABEL: @band_land_left1(
88 ; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
89 ; CHECK-NEXT: ret i1 [[C]]
92 %res = select i1 %c, i1 %A, i1 false
95 define i1 @band_land_left2(i1 %A, i1 %B) {
96 ; CHECK-LABEL: @band_land_left2(
97 ; CHECK-NEXT: [[C:%.*]] = and i1 [[B:%.*]], [[A:%.*]]
98 ; CHECK-NEXT: ret i1 [[C]]
101 %res = select i1 %c, i1 %A, i1 false
106 define i1 @band_lor_left1(i1 %A, i1 %B) {
107 ; CHECK-LABEL: @band_lor_left1(
108 ; CHECK-NEXT: ret i1 [[A:%.*]]
111 %res = select i1 %c, i1 true, i1 %A
114 define i1 @band_lor_left2(i1 %A, i1 %B) {
115 ; CHECK-LABEL: @band_lor_left2(
116 ; CHECK-NEXT: ret i1 [[A:%.*]]
119 %res = select i1 %c, i1 true, i1 %A
124 define i1 @lor_land_left1(i1 %A, i1 %B) {
125 ; CHECK-LABEL: @lor_land_left1(
126 ; CHECK-NEXT: ret i1 [[A:%.*]]
128 %c = select i1 %A, i1 true, i1 %B
129 %res = select i1 %c, i1 %A, i1 false
132 define i1 @lor_land_left2(i1 %A, i1 %B) {
133 ; CHECK-LABEL: @lor_land_left2(
134 ; CHECK-NEXT: ret i1 [[A:%.*]]
136 %c = select i1 %B, i1 true, i1 %A
137 %res = select i1 %c, i1 %A, i1 false
142 define i1 @lor_band_left1(i1 %A, i1 %B) {
143 ; CHECK-LABEL: @lor_band_left1(
144 ; CHECK-NEXT: ret i1 [[A:%.*]]
146 %c = select i1 %A, i1 true, i1 %B
150 define i1 @lor_band_left2(i1 %A, i1 %B) {
151 ; CHECK-LABEL: @lor_band_left2(
152 ; CHECK-NEXT: ret i1 [[A:%.*]]
154 %c = select i1 %B, i1 true, i1 %A
160 define i1 @lor_lor_left1(i1 %A, i1 %B) {
161 ; CHECK-LABEL: @lor_lor_left1(
162 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
163 ; CHECK-NEXT: ret i1 [[C]]
165 %c = select i1 %A, i1 true, i1 %B
166 %res = select i1 %c, i1 true, i1 %A
169 define i1 @lor_lor_left2(i1 %A, i1 %B) {
170 ; CHECK-LABEL: @lor_lor_left2(
171 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
172 ; CHECK-NEXT: ret i1 [[RES]]
174 %c = select i1 %B, i1 true, i1 %A
175 %res = select i1 %c, i1 true, i1 %A
180 define i1 @lor_bor_left1(i1 %A, i1 %B) {
181 ; CHECK-LABEL: @lor_bor_left1(
182 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
183 ; CHECK-NEXT: ret i1 [[C]]
185 %c = select i1 %A, i1 true, i1 %B
189 define i1 @lor_bor_left2(i1 %A, i1 %B) {
190 ; CHECK-LABEL: @lor_bor_left2(
191 ; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
192 ; CHECK-NEXT: ret i1 [[C]]
194 %c = select i1 %B, i1 true, i1 %A
200 define i1 @bor_land_left1(i1 %A, i1 %B) {
201 ; CHECK-LABEL: @bor_land_left1(
202 ; CHECK-NEXT: ret i1 [[A:%.*]]
205 %res = select i1 %c, i1 %A, i1 false
208 define i1 @bor_land_left2(i1 %A, i1 %B) {
209 ; CHECK-LABEL: @bor_land_left2(
210 ; CHECK-NEXT: ret i1 [[A:%.*]]
213 %res = select i1 %c, i1 %A, i1 false
218 define i1 @bor_lor_left1(i1 %A, i1 %B) {
219 ; CHECK-LABEL: @bor_lor_left1(
220 ; CHECK-NEXT: [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
221 ; CHECK-NEXT: ret i1 [[C]]
224 %res = select i1 %c, i1 true, i1 %A
227 define i1 @bor_lor_left2(i1 %A, i1 %B) {
228 ; CHECK-LABEL: @bor_lor_left2(
229 ; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], [[A:%.*]]
230 ; CHECK-NEXT: ret i1 [[C]]
233 %res = select i1 %c, i1 true, i1 %A
237 ; --- A op (A op' B) / A op (B op' A) ---
240 define i1 @land_land_right1(i1 %A, i1 %B) {
241 ; CHECK-LABEL: @land_land_right1(
242 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
243 ; CHECK-NEXT: ret i1 [[RES]]
245 %c = select i1 %A, i1 %B, i1 false
246 %res = select i1 %A, i1 %c, i1 false
249 define i1 @land_land_right2(i1 %A, i1 %B) {
250 ; CHECK-LABEL: @land_land_right2(
251 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
252 ; CHECK-NEXT: ret i1 [[RES]]
254 %c = select i1 %B, i1 %A, i1 false
255 %res = select i1 %A, i1 %c, i1 false
260 define i1 @land_band_right1(i1 %A, i1 %B) {
261 ; CHECK-LABEL: @land_band_right1(
262 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
263 ; CHECK-NEXT: ret i1 [[C]]
265 %c = select i1 %A, i1 %B, i1 false
269 define i1 @land_band_right2(i1 %A, i1 %B) {
270 ; CHECK-LABEL: @land_band_right2(
271 ; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
272 ; CHECK-NEXT: ret i1 [[C]]
274 %c = select i1 %B, i1 %A, i1 false
280 define i1 @land_lor_right1(i1 %A, i1 %B) {
281 ; CHECK-LABEL: @land_lor_right1(
282 ; CHECK-NEXT: ret i1 [[A:%.*]]
284 %c = select i1 %A, i1 %B, i1 false
285 %res = select i1 %A, i1 true, i1 %c
288 define i1 @land_lor_right2(i1 %A, i1 %B) {
289 ; CHECK-LABEL: @land_lor_right2(
290 ; CHECK-NEXT: ret i1 [[A:%.*]]
292 %c = select i1 %B, i1 %A, i1 false
293 %res = select i1 %A, i1 true, i1 %c
297 define <2 x i1> @land_lor_right1_vec(<2 x i1> %A, <2 x i1> %B) {
298 ; CHECK-LABEL: @land_lor_right1_vec(
299 ; CHECK-NEXT: ret <2 x i1> [[A:%.*]]
301 %c = select <2 x i1> %A, <2 x i1> %B, <2 x i1> zeroinitializer
302 %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c
305 define <2 x i1> @land_lor_right2_vec(<2 x i1> %A, <2 x i1> %B) {
306 ; CHECK-LABEL: @land_lor_right2_vec(
307 ; CHECK-NEXT: ret <2 x i1> [[A:%.*]]
309 %c = select <2 x i1> %B, <2 x i1> %A, <2 x i1> zeroinitializer
310 %res = select <2 x i1> %A, <2 x i1> <i1 true, i1 true>, <2 x i1> %c
315 define i1 @land_bor_right1(i1 %A, i1 %B) {
316 ; CHECK-LABEL: @land_bor_right1(
317 ; CHECK-NEXT: ret i1 [[A:%.*]]
319 %c = select i1 %A, i1 %B, i1 false
323 define i1 @land_bor_right2(i1 %A, i1 %B) {
324 ; CHECK-LABEL: @land_bor_right2(
325 ; CHECK-NEXT: ret i1 [[A:%.*]]
327 %c = select i1 %B, i1 %A, i1 false
333 define i1 @band_land_right1(i1 %A, i1 %B) {
334 ; CHECK-LABEL: @band_land_right1(
335 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
336 ; CHECK-NEXT: ret i1 [[RES]]
339 %res = select i1 %A, i1 %c, i1 false
342 define i1 @band_land_right2(i1 %A, i1 %B) {
343 ; CHECK-LABEL: @band_land_right2(
344 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
345 ; CHECK-NEXT: ret i1 [[RES]]
348 %res = select i1 %A, i1 %c, i1 false
353 define i1 @band_lor_right1(i1 %A, i1 %B) {
354 ; CHECK-LABEL: @band_lor_right1(
355 ; CHECK-NEXT: ret i1 [[A:%.*]]
358 %res = select i1 %A, i1 true, i1 %c
361 define i1 @band_lor_right2(i1 %A, i1 %B) {
362 ; CHECK-LABEL: @band_lor_right2(
363 ; CHECK-NEXT: ret i1 [[A:%.*]]
366 %res = select i1 %A, i1 true, i1 %c
371 define i1 @lor_land_right1(i1 %A, i1 %B) {
372 ; CHECK-LABEL: @lor_land_right1(
373 ; CHECK-NEXT: ret i1 [[A:%.*]]
375 %c = select i1 %A, i1 true, i1 %B
376 %res = select i1 %A, i1 %c, i1 false
379 define i1 @lor_land_right2(i1 %A, i1 %B) {
380 ; CHECK-LABEL: @lor_land_right2(
381 ; CHECK-NEXT: ret i1 [[A:%.*]]
383 %c = select i1 %B, i1 true, i1 %A
384 %res = select i1 %A, i1 %c, i1 false
389 define i1 @lor_band_right1(i1 %A, i1 %B) {
390 ; CHECK-LABEL: @lor_band_right1(
391 ; CHECK-NEXT: ret i1 [[A:%.*]]
393 %c = select i1 %A, i1 true, i1 %B
397 define i1 @lor_band_right2(i1 %A, i1 %B) {
398 ; CHECK-LABEL: @lor_band_right2(
399 ; CHECK-NEXT: ret i1 [[A:%.*]]
401 %c = select i1 %B, i1 true, i1 %A
407 define i1 @lor_lor_right1(i1 %A, i1 %B) {
408 ; CHECK-LABEL: @lor_lor_right1(
409 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
410 ; CHECK-NEXT: ret i1 [[RES]]
412 %c = select i1 %A, i1 true, i1 %B
413 %res = select i1 %A, i1 true, i1 %c
416 define i1 @lor_lor_right2(i1 %A, i1 %B) {
417 ; CHECK-LABEL: @lor_lor_right2(
418 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
419 ; CHECK-NEXT: ret i1 [[RES]]
421 %c = select i1 %B, i1 true, i1 %A
422 %res = select i1 %A, i1 true, i1 %c
427 define i1 @lor_bor_right1(i1 %A, i1 %B) {
428 ; CHECK-LABEL: @lor_bor_right1(
429 ; CHECK-NEXT: [[C:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
430 ; CHECK-NEXT: ret i1 [[C]]
432 %c = select i1 %A, i1 true, i1 %B
436 define i1 @lor_bor_right2(i1 %A, i1 %B) {
437 ; CHECK-LABEL: @lor_bor_right2(
438 ; CHECK-NEXT: [[C:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
439 ; CHECK-NEXT: ret i1 [[C]]
441 %c = select i1 %B, i1 true, i1 %A
447 define i1 @bor_land_right1(i1 %A, i1 %B) {
448 ; CHECK-LABEL: @bor_land_right1(
449 ; CHECK-NEXT: ret i1 [[A:%.*]]
452 %res = select i1 %A, i1 %c, i1 false
455 define i1 @bor_land_right2(i1 %A, i1 %B) {
456 ; CHECK-LABEL: @bor_land_right2(
457 ; CHECK-NEXT: ret i1 [[A:%.*]]
460 %res = select i1 %A, i1 %c, i1 false
465 define i1 @bor_lor_right1(i1 %A, i1 %B) {
466 ; CHECK-LABEL: @bor_lor_right1(
467 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
468 ; CHECK-NEXT: ret i1 [[RES]]
471 %res = select i1 %A, i1 true, i1 %c
474 define i1 @bor_lor_right2(i1 %A, i1 %B) {
475 ; CHECK-LABEL: @bor_lor_right2(
476 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
477 ; CHECK-NEXT: ret i1 [[RES]]
480 %res = select i1 %A, i1 true, i1 %c
484 ; Value equivalence substitution does not account for vector
485 ; transforms, so it needs a scalar condition operand.
486 ; For example, this would miscompile if %a = {1, 0}.
488 define <2 x i1> @PR50500_trueval(<2 x i1> %a, <2 x i1> %b) {
489 ; CHECK-LABEL: @PR50500_trueval(
490 ; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
491 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[S]], <2 x i1> [[B:%.*]]
492 ; CHECK-NEXT: ret <2 x i1> [[R]]
494 %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
495 %r = select <2 x i1> %a, <2 x i1> %s, <2 x i1> %b
499 define <2 x i1> @PR50500_falseval(<2 x i1> %a, <2 x i1> %b) {
500 ; CHECK-LABEL: @PR50500_falseval(
501 ; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[A:%.*]], <2 x i1> poison, <2 x i32> <i32 1, i32 0>
502 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B:%.*]], <2 x i1> [[S]]
503 ; CHECK-NEXT: ret <2 x i1> [[R]]
505 %s = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> <i32 1, i32 0>
506 %r = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %s