1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64"
8 define i32 @test12(i32 %A) {
9 ; CHECK-LABEL: @test12(
10 ; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 8
11 ; CHECK-NEXT: ret i32 [[C]]
18 define i32 @test13(i32 %A) {
19 ; CHECK-LABEL: @test13(
20 ; CHECK-NEXT: ret i32 8
28 define i1 @test14(i32 %A, i32 %B) {
29 ; CHECK-LABEL: @test14(
30 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
31 ; CHECK-NEXT: ret i1 [[TMP1]]
33 %C1 = icmp ult i32 %A, %B
34 %C2 = icmp ugt i32 %A, %B
35 ; (A < B) | (A > B) === A != B
40 define i1 @test14_logical(i32 %A, i32 %B) {
41 ; CHECK-LABEL: @test14_logical(
42 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
43 ; CHECK-NEXT: ret i1 [[TMP1]]
45 %C1 = icmp ult i32 %A, %B
46 %C2 = icmp ugt i32 %A, %B
47 ; (A < B) | (A > B) === A != B
48 %D = select i1 %C1, i1 true, i1 %C2
52 define i1 @test15(i32 %A, i32 %B) {
53 ; CHECK-LABEL: @test15(
54 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
55 ; CHECK-NEXT: ret i1 [[TMP1]]
57 %C1 = icmp ult i32 %A, %B
58 %C2 = icmp eq i32 %A, %B
59 ; (A < B) | (A == B) === A <= B
64 define i1 @test15_logical(i32 %A, i32 %B) {
65 ; CHECK-LABEL: @test15_logical(
66 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
67 ; CHECK-NEXT: ret i1 [[TMP1]]
69 %C1 = icmp ult i32 %A, %B
70 %C2 = icmp eq i32 %A, %B
71 ; (A < B) | (A == B) === A <= B
72 %D = select i1 %C1, i1 true, i1 %C2
76 define i32 @test16(i32 %A) {
77 ; CHECK-LABEL: @test16(
78 ; CHECK-NEXT: ret i32 [[A:%.*]]
83 ; %D = and int %B, -1 == %B
88 define i32 @test17(i32 %A) {
89 ; CHECK-LABEL: @test17(
90 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5
91 ; CHECK-NEXT: ret i32 [[D]]
100 define i1 @test18(i32 %A) {
101 ; CHECK-LABEL: @test18(
102 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
103 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49
104 ; CHECK-NEXT: ret i1 [[TMP1]]
106 %B = icmp sge i32 %A, 100
107 %C = icmp slt i32 %A, 50
112 define i1 @test18_logical(i32 %A) {
113 ; CHECK-LABEL: @test18_logical(
114 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
115 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49
116 ; CHECK-NEXT: ret i1 [[TMP1]]
118 %B = icmp sge i32 %A, 100
119 %C = icmp slt i32 %A, 50
120 %D = select i1 %B, i1 true, i1 %C
124 ; FIXME: Vectors should fold too.
125 define <2 x i1> @test18vec(<2 x i32> %A) {
126 ; CHECK-LABEL: @test18vec(
127 ; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 99, i32 99>
128 ; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 50, i32 50>
129 ; CHECK-NEXT: [[D:%.*]] = or <2 x i1> [[B]], [[C]]
130 ; CHECK-NEXT: ret <2 x i1> [[D]]
132 %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
133 %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
134 %D = or <2 x i1> %B, %C
138 define i32 @test20(i32 %x) {
139 ; CHECK-LABEL: @test20(
140 ; CHECK-NEXT: ret i32 [[X:%.*]]
147 define i32 @test21(i32 %t1) {
148 ; CHECK-LABEL: @test21(
149 ; CHECK-NEXT: [[T1_MASK1:%.*]] = add i32 [[T1:%.*]], 2
150 ; CHECK-NEXT: ret i32 [[T1_MASK1]]
152 %t1.mask1 = add i32 %t1, 2
153 %t3 = and i32 %t1.mask1, -2
156 %t6 = or i32 %t5, %t3
160 define i32 @test22(i32 %B) {
161 ; CHECK-LABEL: @test22(
162 ; CHECK-NEXT: ret i32 [[B:%.*]]
164 %ELIM41 = and i32 %B, 1
165 %ELIM7 = and i32 %B, -2
166 %ELIM5 = or i32 %ELIM41, %ELIM7
170 define i16 @test23(i16 %A) {
171 ; CHECK-LABEL: @test23(
172 ; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1
173 ; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575
174 ; CHECK-NEXT: ret i16 [[D]]
178 %C = or i16 %B, -32768
179 %D = xor i16 %C, 8193
183 define <2 x i16> @test23vec(<2 x i16> %A) {
184 ; CHECK-LABEL: @test23vec(
185 ; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1>
186 ; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575>
187 ; CHECK-NEXT: ret <2 x i16> [[D]]
189 %B = lshr <2 x i16> %A, <i16 1, i16 1>
191 %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
192 %D = xor <2 x i16> %C, <i16 8193, i16 8193>
197 define i1 @test25(i32 %A, i32 %B) {
198 ; CHECK-LABEL: @test25(
199 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
200 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
201 ; CHECK-NEXT: [[F:%.*]] = and i1 [[C]], [[D]]
202 ; CHECK-NEXT: ret i1 [[F]]
204 %C = icmp eq i32 %A, 0
205 %D = icmp eq i32 %B, 57
211 define i1 @test25_logical(i32 %A, i32 %B) {
212 ; CHECK-LABEL: @test25_logical(
213 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
214 ; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
215 ; CHECK-NEXT: [[E:%.*]] = select i1 [[C]], i1 [[D]], i1 false
216 ; CHECK-NEXT: ret i1 [[E]]
218 %C = icmp eq i32 %A, 0
219 %D = icmp eq i32 %B, 57
220 %E = select i1 %C, i1 true, i1 %D
226 define i1 @test26(i32 %A, i32 %B) {
227 ; CHECK-LABEL: @test26(
228 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
229 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
230 ; CHECK-NEXT: ret i1 [[TMP2]]
232 %C1 = icmp eq i32 %A, 0
233 %C2 = icmp eq i32 %B, 0
234 ; (A == 0) & (A == 0) --> (A|B) == 0
239 define i1 @test26_logical(i32 %A, i32 %B) {
240 ; CHECK-LABEL: @test26_logical(
241 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
242 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
243 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
244 ; CHECK-NEXT: ret i1 [[D]]
246 %C1 = icmp eq i32 %A, 0
247 %C2 = icmp eq i32 %B, 0
248 ; (A == 0) & (A == 0) --> (A|B) == 0
249 %D = select i1 %C1, i1 %C2, i1 false
253 define i1 @test27(i32* %A, i32* %B) {
254 ; CHECK-LABEL: @test27(
255 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
256 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null
257 ; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
258 ; CHECK-NEXT: ret i1 [[E]]
260 %C1 = ptrtoint i32* %A to i32
261 %C2 = ptrtoint i32* %B to i32
263 %E = icmp eq i32 %D, 0
267 define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) {
268 ; CHECK-LABEL: @test27vec(
269 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer
270 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer
271 ; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
272 ; CHECK-NEXT: ret <2 x i1> [[E]]
274 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
275 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
276 %D = or <2 x i32> %C1, %C2
277 %E = icmp eq <2 x i32> %D, zeroinitializer
282 define i1 @test28(i32 %A, i32 %B) {
283 ; CHECK-LABEL: @test28(
284 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
285 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
286 ; CHECK-NEXT: ret i1 [[TMP2]]
288 %C1 = icmp ne i32 %A, 0
289 %C2 = icmp ne i32 %B, 0
290 ; (A != 0) | (A != 0) --> (A|B) != 0
295 define i1 @test28_logical(i32 %A, i32 %B) {
296 ; CHECK-LABEL: @test28_logical(
297 ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
298 ; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
299 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
300 ; CHECK-NEXT: ret i1 [[D]]
302 %C1 = icmp ne i32 %A, 0
303 %C2 = icmp ne i32 %B, 0
304 ; (A != 0) | (A != 0) --> (A|B) != 0
305 %D = select i1 %C1, i1 true, i1 %C2
309 define i1 @test29(i32* %A, i32* %B) {
310 ; CHECK-LABEL: @test29(
311 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
312 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null
313 ; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
314 ; CHECK-NEXT: ret i1 [[E]]
316 %C1 = ptrtoint i32* %A to i32
317 %C2 = ptrtoint i32* %B to i32
319 %E = icmp ne i32 %D, 0
323 define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) {
324 ; CHECK-LABEL: @test29vec(
325 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer
326 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer
327 ; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
328 ; CHECK-NEXT: ret <2 x i1> [[E]]
330 %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
331 %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
332 %D = or <2 x i32> %C1, %C2
333 %E = icmp ne <2 x i32> %D, zeroinitializer
338 define i32 @test30(i32 %A) {
339 ; CHECK-LABEL: @test30(
340 ; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312
341 ; CHECK-NEXT: [[E:%.*]] = or i32 [[D]], 32962
342 ; CHECK-NEXT: ret i32 [[E]]
344 %B = or i32 %A, 32962
345 %C = and i32 %A, -65536
346 %D = and i32 %B, 40186
351 define <2 x i32> @test30vec(<2 x i32> %A) {
352 ; CHECK-LABEL: @test30vec(
353 ; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -65536, i32 -65536>
354 ; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 7224, i32 7224>
355 ; CHECK-NEXT: [[D:%.*]] = or <2 x i32> [[B]], <i32 32962, i32 32962>
356 ; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[D]], [[C]]
357 ; CHECK-NEXT: ret <2 x i32> [[E]]
359 %B = or <2 x i32> %A, <i32 32962, i32 32962>
360 %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
361 %D = and <2 x i32> %B, <i32 40186, i32 40186>
362 %E = or <2 x i32> %D, %C
367 define i64 @test31(i64 %A) {
368 ; CHECK-LABEL: @test31(
369 ; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984
370 ; CHECK-NEXT: [[F:%.*]] = or i64 [[E]], 32962
371 ; CHECK-NEXT: ret i64 [[F]]
376 %C = or i64 %A, 32768
377 %E = and i64 %C, 4294941696
383 define <2 x i64> @test31vec(<2 x i64> %A) {
384 ; CHECK-LABEL: @test31vec(
385 ; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984>
386 ; CHECK-NEXT: [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962>
387 ; CHECK-NEXT: ret <2 x i64> [[F]]
389 %B = or <2 x i64> %A, <i64 194, i64 194>
390 %D = and <2 x i64> %B, <i64 250, i64 250>
392 %C = or <2 x i64> %A, <i64 32768, i64 32768>
393 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
395 %F = or <2 x i64> %D, %E
399 ; codegen is mature enough to handle vector selects.
400 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
401 ; CHECK-LABEL: @test32(
402 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
403 ; CHECK-NEXT: ret <4 x i32> [[TMP1]]
405 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
406 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
407 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
408 %and.i = and <4 x i32> %vecinit6.i191, %neg.i
409 %or.i = or <4 x i32> %and.i, %and.i129
413 define i1 @test33(i1 %X, i1 %Y) {
414 ; CHECK-LABEL: @test33(
415 ; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
416 ; CHECK-NEXT: ret i1 [[A]]
423 define i1 @test33_logical(i1 %X, i1 %Y) {
424 ; CHECK-LABEL: @test33_logical(
425 ; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
426 ; CHECK-NEXT: ret i1 [[A]]
428 %a = select i1 %X, i1 true, i1 %Y
429 %b = select i1 %a, i1 true, i1 %X
433 define i32 @test34(i32 %X, i32 %Y) {
434 ; CHECK-LABEL: @test34(
435 ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
436 ; CHECK-NEXT: ret i32 [[A]]
443 define i32 @test35(i32 %a, i32 %b) {
444 ; CHECK-LABEL: @test35(
445 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
446 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135
447 ; CHECK-NEXT: ret i32 [[TMP2]]
454 define i1 @test36(i32 %x) {
455 ; CHECK-LABEL: @test36(
456 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
457 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
458 ; CHECK-NEXT: ret i1 [[TMP2]]
460 %cmp1 = icmp eq i32 %x, 23
461 %cmp2 = icmp eq i32 %x, 24
462 %ret1 = or i1 %cmp1, %cmp2
463 %cmp3 = icmp eq i32 %x, 25
464 %ret2 = or i1 %ret1, %cmp3
468 define i1 @test36_logical(i32 %x) {
469 ; CHECK-LABEL: @test36_logical(
470 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23
471 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
472 ; CHECK-NEXT: ret i1 [[TMP2]]
474 %cmp1 = icmp eq i32 %x, 23
475 %cmp2 = icmp eq i32 %x, 24
476 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
477 %cmp3 = icmp eq i32 %x, 25
478 %ret2 = select i1 %ret1, i1 true, i1 %cmp3
482 define i1 @test37(i32 %x) {
483 ; CHECK-LABEL: @test37(
484 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 7
485 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[ADD1]], 31
486 ; CHECK-NEXT: ret i1 [[TMP1]]
488 %add1 = add i32 %x, 7
489 %cmp1 = icmp ult i32 %add1, 30
490 %cmp2 = icmp eq i32 %x, 23
491 %ret1 = or i1 %cmp1, %cmp2
495 define i1 @test37_logical(i32 %x) {
496 ; CHECK-LABEL: @test37_logical(
497 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 7
498 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[ADD1]], 31
499 ; CHECK-NEXT: ret i1 [[TMP1]]
501 %add1 = add i32 %x, 7
502 %cmp1 = icmp ult i32 %add1, 30
503 %cmp2 = icmp eq i32 %x, 23
504 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
508 define <2 x i1> @test37_uniform(<2 x i32> %x) {
509 ; CHECK-LABEL: @test37_uniform(
510 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
511 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 30>
512 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 23>
513 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
514 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
516 %add1 = add <2 x i32> %x, <i32 7, i32 7>
517 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
518 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
519 %ret1 = or <2 x i1> %cmp1, %cmp2
523 define <2 x i1> @test37_undef(<2 x i32> %x) {
524 ; CHECK-LABEL: @test37_undef(
525 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 undef>
526 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 undef>
527 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 undef>
528 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
529 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
531 %add1 = add <2 x i32> %x, <i32 7, i32 undef>
532 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 undef>
533 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 undef>
534 %ret1 = or <2 x i1> %cmp1, %cmp2
538 define i1 @test38(i32 %x) {
539 ; CHECK-LABEL: @test38(
540 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 7
541 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 23
542 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[ADD1]], 30
543 ; CHECK-NEXT: [[RET1:%.*]] = or i1 [[CMP1]], [[CMP2]]
544 ; CHECK-NEXT: ret i1 [[RET1]]
546 %add1 = add i32 %x, 7
547 %cmp1 = icmp eq i32 %x, 23
548 %cmp2 = icmp ult i32 %add1, 30
549 %ret1 = or i1 %cmp1, %cmp2
553 define i1 @test38_logical(i32 %x) {
554 ; CHECK-LABEL: @test38_logical(
555 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 7
556 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 23
557 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[ADD1]], 30
558 ; CHECK-NEXT: [[RET1:%.*]] = or i1 [[CMP1]], [[CMP2]]
559 ; CHECK-NEXT: ret i1 [[RET1]]
561 %add1 = add i32 %x, 7
562 %cmp1 = icmp eq i32 %x, 23
563 %cmp2 = icmp ult i32 %add1, 30
564 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
568 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
569 ; CHECK-LABEL: @test38_nonuniform(
570 ; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
571 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
572 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
573 ; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
574 ; CHECK-NEXT: ret <2 x i1> [[RET1]]
576 %add1 = add <2 x i32> %x, <i32 7, i32 24>
577 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
578 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
579 %ret1 = or <2 x i1> %cmp1, %cmp2
583 define i32 @orsext_to_sel(i32 %x, i1 %y) {
584 ; CHECK-LABEL: @orsext_to_sel(
585 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i32 -1, i32 [[X:%.*]]
586 ; CHECK-NEXT: ret i32 [[OR]]
588 %sext = sext i1 %y to i32
589 %or = or i32 %sext, %x
593 define i32 @orsext_to_sel_swap(i32 %x, i1 %y) {
594 ; CHECK-LABEL: @orsext_to_sel_swap(
595 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i32 -1, i32 [[X:%.*]]
596 ; CHECK-NEXT: ret i32 [[OR]]
598 %sext = sext i1 %y to i32
599 %or = or i32 %x, %sext
603 define i32 @orsext_to_sel_multi_use(i32 %x, i1 %y) {
604 ; CHECK-LABEL: @orsext_to_sel_multi_use(
605 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
606 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEXT]], [[X:%.*]]
607 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[OR]], [[SEXT]]
608 ; CHECK-NEXT: ret i32 [[ADD]]
610 %sext = sext i1 %y to i32
611 %or = or i32 %sext, %x
612 %add = add i32 %sext, %or
616 define <2 x i32> @orsext_to_sel_vec(<2 x i32> %x, <2 x i1> %y) {
617 ; CHECK-LABEL: @orsext_to_sel_vec(
618 ; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> <i32 -1, i32 -1>, <2 x i32> [[X:%.*]]
619 ; CHECK-NEXT: ret <2 x i32> [[OR]]
621 %sext = sext <2 x i1> %y to <2 x i32>
622 %or = or <2 x i32> %sext, %x
626 define <2 x i132> @orsext_to_sel_vec_swap(<2 x i132> %x, <2 x i1> %y) {
627 ; CHECK-LABEL: @orsext_to_sel_vec_swap(
628 ; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i132> <i132 -1, i132 -1>, <2 x i132> [[X:%.*]]
629 ; CHECK-NEXT: ret <2 x i132> [[OR]]
631 %sext = sext <2 x i1> %y to <2 x i132>
632 %or = or <2 x i132> %x, %sext
636 ; (~A & B) | A --> A | B
638 define i32 @test39a(i32 %a, float %b) {
639 ; CHECK-LABEL: @test39a(
640 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
641 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
642 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
643 ; CHECK-NEXT: ret i32 [[OR]]
645 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
646 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
647 %nota = xor i32 %a1, -1
648 %and = and i32 %nota, %b1
649 %or = or i32 %and, %a1
653 ; Commute 'and' operands:
654 ; (B & ~A) | A --> A | B
656 define i32 @test39b(i32 %a, float %b) {
657 ; CHECK-LABEL: @test39b(
658 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
659 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
660 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
661 ; CHECK-NEXT: ret i32 [[OR]]
663 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
664 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
665 %nota = xor i32 %a1, -1
666 %and = and i32 %b1, %nota
667 %or = or i32 %and, %a1
671 ; Commute 'or' operands:
672 ; A | (~A & B) --> A | B
674 define i32 @test39c(i32 %a, float %b) {
675 ; CHECK-LABEL: @test39c(
676 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
677 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
678 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
679 ; CHECK-NEXT: ret i32 [[OR]]
681 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
682 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
683 %nota = xor i32 %a1, -1
684 %and = and i32 %nota, %b1
685 %or = or i32 %a1, %and
689 ; Commute 'and' operands:
690 ; A | (B & ~A) --> A | B
692 define i32 @test39d(i32 %a, float %b) {
693 ; CHECK-LABEL: @test39d(
694 ; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42
695 ; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32
696 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
697 ; CHECK-NEXT: ret i32 [[OR]]
699 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
700 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
701 %nota = xor i32 %a1, -1
702 %and = and i32 %b1, %nota
703 %or = or i32 %a1, %and
707 define i32 @test40(i32 %a, i32 %b) {
708 ; CHECK-LABEL: @test40(
709 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
710 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
711 ; CHECK-NEXT: ret i32 [[OR]]
713 %and = and i32 %a, %b
714 %xor = xor i32 %a, -1
715 %or = or i32 %and, %xor
719 define i32 @test40b(i32 %a, i32 %b) {
720 ; CHECK-LABEL: @test40b(
721 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
722 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
723 ; CHECK-NEXT: ret i32 [[OR]]
725 %and = and i32 %b, %a
726 %xor = xor i32 %a, -1
727 %or = or i32 %and, %xor
731 define i32 @test40c(i32 %a, i32 %b) {
732 ; CHECK-LABEL: @test40c(
733 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
734 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
735 ; CHECK-NEXT: ret i32 [[OR]]
737 %and = and i32 %b, %a
738 %xor = xor i32 %a, -1
739 %or = or i32 %xor, %and
743 define i32 @test40d(i32 %a, i32 %b) {
744 ; CHECK-LABEL: @test40d(
745 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1
746 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
747 ; CHECK-NEXT: ret i32 [[OR]]
749 %and = and i32 %a, %b
750 %xor = xor i32 %a, -1
751 %or = or i32 %xor, %and
755 define i32 @test45(i32 %x, i32 %y, i32 %z) {
756 ; CHECK-LABEL: @test45(
757 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
758 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
759 ; CHECK-NEXT: ret i32 [[OR1]]
762 %and = and i32 %x, %or
763 %or1 = or i32 %and, %y
767 define i1 @test46(i8 signext %c) {
768 ; CHECK-LABEL: @test46(
769 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
770 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
771 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
772 ; CHECK-NEXT: ret i1 [[TMP3]]
774 %c.off = add i8 %c, -97
775 %cmp1 = icmp ult i8 %c.off, 26
776 %c.off17 = add i8 %c, -65
777 %cmp2 = icmp ult i8 %c.off17, 26
778 %or = or i1 %cmp1, %cmp2
782 define i1 @test46_logical(i8 signext %c) {
783 ; CHECK-LABEL: @test46_logical(
784 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
785 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
786 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
787 ; CHECK-NEXT: ret i1 [[TMP3]]
789 %c.off = add i8 %c, -97
790 %cmp1 = icmp ult i8 %c.off, 26
791 %c.off17 = add i8 %c, -65
792 %cmp2 = icmp ult i8 %c.off17, 26
793 %or = select i1 %cmp1, i1 true, i1 %cmp2
797 define <2 x i1> @test46_uniform(<2 x i8> %c) {
798 ; CHECK-LABEL: @test46_uniform(
799 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 -97>
800 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 26>
801 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 -65>
802 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 26>
803 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
804 ; CHECK-NEXT: ret <2 x i1> [[OR]]
806 %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
807 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
808 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
809 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
810 %or = or <2 x i1> %cmp1, %cmp2
814 define <2 x i1> @test46_undef(<2 x i8> %c) {
815 ; CHECK-LABEL: @test46_undef(
816 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 undef>
817 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 undef>
818 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 undef>
819 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 undef>
820 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
821 ; CHECK-NEXT: ret <2 x i1> [[OR]]
823 %c.off = add <2 x i8> %c, <i8 -97, i8 undef>
824 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 undef>
825 %c.off17 = add <2 x i8> %c, <i8 -65, i8 undef>
826 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 undef>
827 %or = or <2 x i1> %cmp1, %cmp2
831 define i1 @test47(i8 signext %c) {
832 ; CHECK-LABEL: @test47(
833 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
834 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
835 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
836 ; CHECK-NEXT: ret i1 [[TMP3]]
838 %c.off = add i8 %c, -65
839 %cmp1 = icmp ule i8 %c.off, 26
840 %c.off17 = add i8 %c, -97
841 %cmp2 = icmp ule i8 %c.off17, 26
842 %or = or i1 %cmp1, %cmp2
846 define i1 @test47_logical(i8 signext %c) {
847 ; CHECK-LABEL: @test47_logical(
848 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
849 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65
850 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
851 ; CHECK-NEXT: ret i1 [[TMP3]]
853 %c.off = add i8 %c, -65
854 %cmp1 = icmp ule i8 %c.off, 26
855 %c.off17 = add i8 %c, -97
856 %cmp2 = icmp ule i8 %c.off17, 26
857 %or = select i1 %cmp1, i1 true, i1 %cmp2
861 define <2 x i1> @test47_nonuniform(<2 x i8> %c) {
862 ; CHECK-LABEL: @test47_nonuniform(
863 ; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
864 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 27, i8 27>
865 ; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
866 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 27, i8 27>
867 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
868 ; CHECK-NEXT: ret <2 x i1> [[OR]]
870 %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
871 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
872 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
873 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
874 %or = or <2 x i1> %cmp1, %cmp2
878 define i32 @test49(i1 %C) {
879 ; CHECK-LABEL: @test49(
880 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
881 ; CHECK-NEXT: ret i32 [[V]]
883 %A = select i1 %C, i32 1000, i32 10
888 define <2 x i32> @test49vec(i1 %C) {
889 ; CHECK-LABEL: @test49vec(
890 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123>
891 ; CHECK-NEXT: ret <2 x i32> [[V]]
893 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
894 %V = or <2 x i32> %A, <i32 123, i32 123>
898 define <2 x i32> @test49vec2(i1 %C) {
899 ; CHECK-LABEL: @test49vec2(
900 ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
901 ; CHECK-NEXT: ret <2 x i32> [[V]]
903 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
904 %V = or <2 x i32> %A, <i32 123, i32 333>
908 define i32 @test50(i1 %which) {
909 ; CHECK-LABEL: @test50(
911 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
913 ; CHECK-NEXT: br label [[FINAL]]
915 ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
916 ; CHECK-NEXT: ret i32 [[A]]
919 br i1 %which, label %final, label %delay
925 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
926 %value = or i32 %A, 123
930 define <2 x i32> @test50vec(i1 %which) {
931 ; CHECK-LABEL: @test50vec(
933 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
935 ; CHECK-NEXT: br label [[FINAL]]
937 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ]
938 ; CHECK-NEXT: ret <2 x i32> [[A]]
941 br i1 %which, label %final, label %delay
947 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
948 %value = or <2 x i32> %A, <i32 123, i32 123>
952 define <2 x i32> @test50vec2(i1 %which) {
953 ; CHECK-LABEL: @test50vec2(
955 ; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
957 ; CHECK-NEXT: br label [[FINAL]]
959 ; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
960 ; CHECK-NEXT: ret <2 x i32> [[A]]
963 br i1 %which, label %final, label %delay
969 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
970 %value = or <2 x i32> %A, <i32 123, i32 333>
974 ; In the next 4 tests, vary the types and predicates for extra coverage.
975 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
977 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
978 ; CHECK-LABEL: @or_andn_cmp_1(
979 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
980 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
981 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
982 ; CHECK-NEXT: ret i1 [[OR]]
984 %x = icmp sgt i32 %a, %b
985 %x_inv = icmp sle i32 %a, %b
986 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
987 %and = and i1 %y, %x_inv
992 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
993 ; CHECK-LABEL: @or_andn_cmp_1_logical(
994 ; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
995 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
996 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
997 ; CHECK-NEXT: ret i1 [[OR]]
999 %x = icmp sgt i32 %a, %b
1000 %x_inv = icmp sle i32 %a, %b
1001 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1002 %and = select i1 %y, i1 %x_inv, i1 false
1003 %or = select i1 %x, i1 true, i1 %and
1008 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1010 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1011 ; CHECK-LABEL: @or_andn_cmp_2(
1012 ; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
1013 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
1014 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
1015 ; CHECK-NEXT: ret <2 x i1> [[OR]]
1017 %x = icmp sge <2 x i32> %a, %b
1018 %x_inv = icmp slt <2 x i32> %a, %b
1019 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering
1020 %and = and <2 x i1> %y, %x_inv
1021 %or = or <2 x i1> %and, %x
1025 ; Commute the 'and':
1026 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1028 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1029 ; CHECK-LABEL: @or_andn_cmp_3(
1030 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1031 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1032 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
1033 ; CHECK-NEXT: ret i1 [[OR]]
1035 %x = icmp ugt i72 %a, %b
1036 %x_inv = icmp ule i72 %a, %b
1037 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1038 %and = and i1 %x_inv, %y
1039 %or = or i1 %x, %and
1043 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1044 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1045 ; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1046 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1047 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1048 ; CHECK-NEXT: ret i1 [[OR]]
1050 %x = icmp ugt i72 %a, %b
1051 %x_inv = icmp ule i72 %a, %b
1052 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
1053 %and = select i1 %x_inv, i1 %y, i1 false
1054 %or = select i1 %x, i1 true, i1 %and
1059 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1061 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1062 ; CHECK-LABEL: @or_andn_cmp_4(
1063 ; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1064 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1065 ; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1066 ; CHECK-NEXT: ret <3 x i1> [[OR]]
1068 %x = icmp eq <3 x i32> %a, %b
1069 %x_inv = icmp ne <3 x i32> %a, %b
1070 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering
1071 %and = and <3 x i1> %x_inv, %y
1072 %or = or <3 x i1> %and, %x
1076 ; In the next 4 tests, vary the types and predicates for extra coverage.
1077 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1079 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1080 ; CHECK-LABEL: @orn_and_cmp_1(
1081 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1082 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1083 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1084 ; CHECK-NEXT: ret i1 [[OR]]
1086 %x = icmp sgt i37 %a, %b
1087 %x_inv = icmp sle i37 %a, %b
1088 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1089 %and = and i1 %y, %x
1090 %or = or i1 %x_inv, %and
1094 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1095 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1096 ; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1097 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1098 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1099 ; CHECK-NEXT: ret i1 [[OR]]
1101 %x = icmp sgt i37 %a, %b
1102 %x_inv = icmp sle i37 %a, %b
1103 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
1104 %and = select i1 %y, i1 %x, i1 false
1105 %or = select i1 %x_inv, i1 true, i1 %and
1110 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1112 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1113 ; CHECK-LABEL: @orn_and_cmp_2(
1114 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1115 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1116 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1117 ; CHECK-NEXT: ret i1 [[OR]]
1119 %x = icmp sge i16 %a, %b
1120 %x_inv = icmp slt i16 %a, %b
1121 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1122 %and = and i1 %y, %x
1123 %or = or i1 %and, %x_inv
1127 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1128 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1129 ; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1130 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1131 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1132 ; CHECK-NEXT: ret i1 [[OR]]
1134 %x = icmp sge i16 %a, %b
1135 %x_inv = icmp slt i16 %a, %b
1136 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
1137 %and = select i1 %y, i1 %x, i1 false
1138 %or = select i1 %and, i1 true, i1 %x_inv
1142 ; Commute the 'and':
1143 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1145 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1146 ; CHECK-LABEL: @orn_and_cmp_3(
1147 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1148 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1149 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1150 ; CHECK-NEXT: ret <4 x i1> [[OR]]
1152 %x = icmp ugt <4 x i32> %a, %b
1153 %x_inv = icmp ule <4 x i32> %a, %b
1154 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering
1155 %and = and <4 x i1> %x, %y
1156 %or = or <4 x i1> %x_inv, %and
1161 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1163 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1164 ; CHECK-LABEL: @orn_and_cmp_4(
1165 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1166 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1167 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1168 ; CHECK-NEXT: ret i1 [[OR]]
1170 %x = icmp eq i32 %a, %b
1171 %x_inv = icmp ne i32 %a, %b
1172 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1173 %and = and i1 %x, %y
1174 %or = or i1 %and, %x_inv
1178 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1179 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1180 ; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1181 ; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1182 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1183 ; CHECK-NEXT: ret i1 [[OR]]
1185 %x = icmp eq i32 %a, %b
1186 %x_inv = icmp ne i32 %a, %b
1187 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
1188 %and = select i1 %x, i1 %y, i1 false
1189 %or = select i1 %and, i1 true, i1 %x_inv
1193 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1194 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1195 ; CHECK-LABEL: @test51(
1196 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31>
1197 ; CHECK-NEXT: ret <16 x i1> [[TMP1]]
1199 %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>
1200 %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>
1201 %tmp3 = or <16 x i1> %tmp, %tmp2
1205 ; This would infinite loop because it reaches a transform
1206 ; that was not expecting a constant-foldable value.
1208 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1209 ; CHECK-LABEL: @PR46712(
1210 ; CHECK-NEXT: entry:
1211 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1213 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1214 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1215 ; CHECK-NEXT: br label [[END]]
1217 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1218 ; CHECK-NEXT: ret i32 [[T5]]
1222 %conv = sext i1 %t2 to i32
1223 %cmp = icmp sge i32 %conv, 1
1224 %conv2 = zext i1 %cmp to i64
1225 br i1 %b, label %true, label %end
1228 %bool4 = icmp eq i64 %conv2, 0
1229 %bool5 = icmp ne i64 %z, 0
1230 %and = and i1 %bool4, %bool5
1231 %sel = select i1 %and, i1 false, i1 true
1235 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1236 %conv8 = zext i1 %t5 to i32
1240 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1241 ; CHECK-LABEL: @PR46712_logical(
1242 ; CHECK-NEXT: entry:
1243 ; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1245 ; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1246 ; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1247 ; CHECK-NEXT: br label [[END]]
1249 ; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1250 ; CHECK-NEXT: ret i32 [[T5]]
1253 %t2 = select i1 %x, i1 true, i1 %y
1254 %conv = sext i1 %t2 to i32
1255 %cmp = icmp sge i32 %conv, 1
1256 %conv2 = zext i1 %cmp to i64
1257 br i1 %b, label %true, label %end
1260 %bool4 = icmp eq i64 %conv2, 0
1261 %bool5 = icmp ne i64 %z, 0
1262 %and = select i1 %bool4, i1 %bool5, i1 false
1263 %sel = select i1 %and, i1 false, i1 true
1267 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1268 %conv8 = zext i1 %t5 to i32
1272 ; (~x & y) | ~(x | y) --> ~x
1273 define i32 @PR38929(i32 %0, i32 %1) {
1274 ; CHECK-LABEL: @PR38929(
1275 ; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1276 ; CHECK-NEXT: ret i32 [[TMP3]]
1286 define i32 @test1(i32 %x, i32 %y) {
1287 ; CHECK-LABEL: @test1(
1288 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1289 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1290 ; CHECK-NEXT: ret i32 [[OR1]]
1292 %xor = xor i32 %y, %x
1294 %neg = xor i32 %or, -1
1295 %or1 = or i32 %xor, %neg
1299 define i32 @test2(i32 %x, i32 %y) {
1300 ; CHECK-LABEL: @test2(
1301 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1302 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1303 ; CHECK-NEXT: ret i32 [[OR1]]
1306 %neg = xor i32 %or, -1
1307 %xor = xor i32 %y, %x
1308 %or1 = or i32 %xor, %neg
1312 define i32 @test3(i32 %x, i32 %y) {
1313 ; CHECK-LABEL: @test3(
1314 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1315 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1316 ; CHECK-NEXT: ret i32 [[OR1]]
1319 %neg = xor i32 %or, -1
1320 %xor = xor i32 %x, %y
1321 %or1 = or i32 %xor, %neg
1325 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1326 ; CHECK-LABEL: @test4_vec(
1327 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1328 ; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
1329 ; CHECK-NEXT: ret <2 x i32> [[OR1]]
1331 %or = or <2 x i32> %y, %x
1332 %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1333 %xor = xor <2 x i32> %y, %x
1334 %or1 = or <2 x i32> %xor, %neg
1338 define i32 @test5_use(i32 %x, i32 %y) {
1339 ; CHECK-LABEL: @test5_use(
1340 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1341 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1342 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1343 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1344 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1345 ; CHECK-NEXT: ret i32 [[OR1]]
1348 %neg = xor i32 %or, -1
1349 %xor = xor i32 %y, %x
1350 call void @use(i32 %neg)
1351 %or1 = or i32 %xor, %neg
1355 define i32 @test5_use2(i32 %x, i32 %y) {
1356 ; CHECK-LABEL: @test5_use2(
1357 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1358 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1359 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1360 ; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1
1361 ; CHECK-NEXT: ret i32 [[OR1]]
1364 %neg = xor i32 %or, -1
1365 %xor = xor i32 %y, %x
1366 call void @use(i32 %xor)
1367 %or1 = or i32 %xor, %neg
1370 define i32 @test5_use3(i32 %x, i32 %y) {
1371 ; CHECK-LABEL: @test5_use3(
1372 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1373 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1
1374 ; CHECK-NEXT: call void @use(i32 [[NEG]])
1375 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1376 ; CHECK-NEXT: call void @use(i32 [[XOR]])
1377 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1378 ; CHECK-NEXT: ret i32 [[OR1]]
1381 %neg = xor i32 %or, -1
1382 call void @use(i32 %neg)
1383 %xor = xor i32 %y, %x
1384 call void @use(i32 %xor)
1385 %or1 = or i32 %xor, %neg