1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; There should be no 'and' instructions left in any test.
5
6define i32 @test1(i32 %A) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    ret i32 0
9;
10  %B = and i32 %A, 0
11  ret i32 %B
12}
13
14define i32 @test2(i32 %A) {
15; CHECK-LABEL: @test2(
16; CHECK-NEXT:    ret i32 %A
17;
18  %B = and i32 %A, -1
19  ret i32 %B
20}
21
22define i1 @test3(i1 %A) {
23; CHECK-LABEL: @test3(
24; CHECK-NEXT:    ret i1 false
25;
26  %B = and i1 %A, false
27  ret i1 %B
28}
29
30define i1 @test4(i1 %A) {
31; CHECK-LABEL: @test4(
32; CHECK-NEXT:    ret i1 %A
33;
34  %B = and i1 %A, true
35  ret i1 %B
36}
37
38define i32 @test5(i32 %A) {
39; CHECK-LABEL: @test5(
40; CHECK-NEXT:    ret i32 %A
41;
42  %B = and i32 %A, %A
43  ret i32 %B
44}
45
46define i1 @test6(i1 %A) {
47; CHECK-LABEL: @test6(
48; CHECK-NEXT:    ret i1 %A
49;
50  %B = and i1 %A, %A
51  ret i1 %B
52}
53
54; A & ~A == 0
55define i32 @test7(i32 %A) {
56; CHECK-LABEL: @test7(
57; CHECK-NEXT:    ret i32 0
58;
59  %NotA = xor i32 %A, -1
60  %B = and i32 %A, %NotA
61  ret i32 %B
62}
63
64; AND associates
65define i8 @test8(i8 %A) {
66; CHECK-LABEL: @test8(
67; CHECK-NEXT:    ret i8 0
68;
69  %B = and i8 %A, 3
70  %C = and i8 %B, 4
71  ret i8 %C
72}
73
74; Test of sign bit, convert to setle %A, 0
75define i1 @test9(i32 %A) {
76; CHECK-LABEL: @test9(
77; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 %A, 0
78; CHECK-NEXT:    ret i1 [[C]]
79;
80  %B = and i32 %A, -2147483648
81  %C = icmp ne i32 %B, 0
82  ret i1 %C
83}
84
85; Test of sign bit, convert to setle %A, 0
86define i1 @test9a(i32 %A) {
87; CHECK-LABEL: @test9a(
88; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 %A, 0
89; CHECK-NEXT:    ret i1 [[C]]
90;
91  %B = and i32 %A, -2147483648
92  %C = icmp ne i32 %B, 0
93  ret i1 %C
94}
95
96define i32 @test10(i32 %A) {
97; CHECK-LABEL: @test10(
98; CHECK-NEXT:    ret i32 1
99;
100  %B = and i32 %A, 12
101  %C = xor i32 %B, 15
102  ; (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
103  %D = and i32 %C, 1
104  ret i32 %D
105}
106
107define i32 @test11(i32 %A, i32* %P) {
108; CHECK-LABEL: @test11(
109; CHECK-NEXT:    [[B:%.*]] = or i32 %A, 3
110; CHECK-NEXT:    [[C:%.*]] = xor i32 [[B]], 12
111; CHECK-NEXT:    store i32 [[C]], i32* %P, align 4
112; CHECK-NEXT:    ret i32 3
113;
114  %B = or i32 %A, 3
115  %C = xor i32 %B, 12
116  ; additional use of C
117  store i32 %C, i32* %P
118  ; %C = and uint %B, 3 --> 3
119  %D = and i32 %C, 3
120  ret i32 %D
121}
122
123define i1 @test12(i32 %A, i32 %B) {
124; CHECK-LABEL: @test12(
125; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %A, %B
126; CHECK-NEXT:    ret i1 [[TMP1]]
127;
128  %C1 = icmp ult i32 %A, %B
129  %C2 = icmp ule i32 %A, %B
130  ; (A < B) & (A <= B) === (A < B)
131  %D = and i1 %C1, %C2
132  ret i1 %D
133}
134
135define i1 @test13(i32 %A, i32 %B) {
136; CHECK-LABEL: @test13(
137; CHECK-NEXT:    ret i1 false
138;
139  %C1 = icmp ult i32 %A, %B
140  %C2 = icmp ugt i32 %A, %B
141  ; (A < B) & (A > B) === false
142  %D = and i1 %C1, %C2
143  ret i1 %D
144}
145
146define i1 @test14(i8 %A) {
147; CHECK-LABEL: @test14(
148; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %A, 0
149; CHECK-NEXT:    ret i1 [[C]]
150;
151  %B = and i8 %A, -128
152  %C = icmp ne i8 %B, 0
153  ret i1 %C
154}
155
156define i8 @test15(i8 %A) {
157; CHECK-LABEL: @test15(
158; CHECK-NEXT:    ret i8 0
159;
160  %B = lshr i8 %A, 7
161  ; Always equals zero
162  %C = and i8 %B, 2
163  ret i8 %C
164}
165
166define i8 @test16(i8 %A) {
167; CHECK-LABEL: @test16(
168; CHECK-NEXT:    ret i8 0
169;
170  %B = shl i8 %A, 2
171  %C = and i8 %B, 3
172  ret i8 %C
173}
174
175define i1 @test18(i32 %A) {
176; CHECK-LABEL: @test18(
177; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 %A, 127
178; CHECK-NEXT:    ret i1 [[C]]
179;
180  %B = and i32 %A, -128
181  ;; C >= 128
182  %C = icmp ne i32 %B, 0
183  ret i1 %C
184}
185
186define <2 x i1> @test18_vec(<2 x i32> %A) {
187; CHECK-LABEL: @test18_vec(
188; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> %A, <i32 127, i32 127>
189; CHECK-NEXT:    ret <2 x i1> [[C]]
190;
191  %B = and <2 x i32> %A, <i32 -128, i32 -128>
192  %C = icmp ne <2 x i32> %B, zeroinitializer
193  ret <2 x i1> %C
194}
195
196define i1 @test18a(i8 %A) {
197; CHECK-LABEL: @test18a(
198; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 %A, 2
199; CHECK-NEXT:    ret i1 [[C]]
200;
201  %B = and i8 %A, -2
202  %C = icmp eq i8 %B, 0
203  ret i1 %C
204}
205
206define <2 x i1> @test18a_vec(<2 x i8> %A) {
207; CHECK-LABEL: @test18a_vec(
208; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> %A, <i8 2, i8 2>
209; CHECK-NEXT:    ret <2 x i1> [[C]]
210;
211  %B = and <2 x i8> %A, <i8 -2, i8 -2>
212  %C = icmp eq <2 x i8> %B, zeroinitializer
213  ret <2 x i1> %C
214}
215
216define i32 @test19(i32 %A) {
217; CHECK-LABEL: @test19(
218; CHECK-NEXT:    [[B:%.*]] = shl i32 %A, 3
219; CHECK-NEXT:    ret i32 [[B]]
220;
221  %B = shl i32 %A, 3
222  ;; Clearing a zero bit
223  %C = and i32 %B, -2
224  ret i32 %C
225}
226
227define i8 @test20(i8 %A) {
228; CHECK-LABEL: @test20(
229; CHECK-NEXT:    [[C:%.*]] = lshr i8 %A, 7
230; CHECK-NEXT:    ret i8 [[C]]
231;
232  %C = lshr i8 %A, 7
233  ;; Unneeded
234  %D = and i8 %C, 1
235  ret i8 %D
236}
237
238define i1 @test23(i32 %A) {
239; CHECK-LABEL: @test23(
240; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 %A, 2
241; CHECK-NEXT:    ret i1 [[TMP1]]
242;
243  %B = icmp sgt i32 %A, 1
244  %C = icmp sle i32 %A, 2
245  %D = and i1 %B, %C
246  ret i1 %D
247}
248
249; FIXME: Vectors should fold too.
250define <2 x i1> @test23vec(<2 x i32> %A) {
251; CHECK-LABEL: @test23vec(
252; CHECK-NEXT:    [[B:%.*]] = icmp sgt <2 x i32> %A, <i32 1, i32 1>
253; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %A, <i32 3, i32 3>
254; CHECK-NEXT:    [[D:%.*]] = and <2 x i1> [[B]], [[C]]
255; CHECK-NEXT:    ret <2 x i1> [[D]]
256;
257  %B = icmp sgt <2 x i32> %A, <i32 1, i32 1>
258  %C = icmp sle <2 x i32> %A, <i32 2, i32 2>
259  %D = and <2 x i1> %B, %C
260  ret <2 x i1> %D
261}
262
263define i1 @test24(i32 %A) {
264; CHECK-LABEL: @test24(
265; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %A, 2
266; CHECK-NEXT:    ret i1 [[TMP1]]
267;
268  %B = icmp sgt i32 %A, 1
269  %C = icmp ne i32 %A, 2
270  ;; A > 2
271  %D = and i1 %B, %C
272  ret i1 %D
273}
274
275define i1 @test25(i32 %A) {
276; CHECK-LABEL: @test25(
277; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 %A, -50
278; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 50
279; CHECK-NEXT:    ret i1 [[TMP1]]
280;
281  %B = icmp sge i32 %A, 50
282  %C = icmp slt i32 %A, 100
283  %D = and i1 %B, %C
284  ret i1 %D
285}
286
287; FIXME: Vectors should fold too.
288define <2 x i1> @test25vec(<2 x i32> %A) {
289; CHECK-LABEL: @test25vec(
290; CHECK-NEXT:    [[B:%.*]] = icmp sgt <2 x i32> %A, <i32 49, i32 49>
291; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %A, <i32 100, i32 100>
292; CHECK-NEXT:    [[D:%.*]] = and <2 x i1> [[B]], [[C]]
293; CHECK-NEXT:    ret <2 x i1> [[D]]
294;
295  %B = icmp sge <2 x i32> %A, <i32 50, i32 50>
296  %C = icmp slt <2 x i32> %A, <i32 100, i32 100>
297  %D = and <2 x i1> %B, %C
298  ret <2 x i1> %D
299}
300
301define i8 @test27(i8 %A) {
302; CHECK-LABEL: @test27(
303; CHECK-NEXT:    ret i8 0
304;
305  %B = and i8 %A, 4
306  %C = sub i8 %B, 16
307  ;; 0xF0
308  %D = and i8 %C, -16
309  %E = add i8 %D, 16
310  ret i8 %E
311}
312
313;; This is just a zero-extending shr.
314define i32 @test28(i32 %X) {
315; CHECK-LABEL: @test28(
316; CHECK-NEXT:    [[Y1:%.*]] = lshr i32 %X, 24
317; CHECK-NEXT:    ret i32 [[Y1]]
318;
319  ;; Sign extend
320  %Y = ashr i32 %X, 24
321  ;; Mask out sign bits
322  %Z = and i32 %Y, 255
323  ret i32 %Z
324}
325
326define i32 @test29(i8 %X) {
327; CHECK-LABEL: @test29(
328; CHECK-NEXT:    [[Y:%.*]] = zext i8 %X to i32
329; CHECK-NEXT:    ret i32 [[Y]]
330;
331  %Y = zext i8 %X to i32
332  ;; Zero extend makes this unneeded.
333  %Z = and i32 %Y, 255
334  ret i32 %Z
335}
336
337define i32 @test30(i1 %X) {
338; CHECK-LABEL: @test30(
339; CHECK-NEXT:    [[Y:%.*]] = zext i1 %X to i32
340; CHECK-NEXT:    ret i32 [[Y]]
341;
342  %Y = zext i1 %X to i32
343  %Z = and i32 %Y, 1
344  ret i32 %Z
345}
346
347define i32 @test31(i1 %X) {
348; CHECK-LABEL: @test31(
349; CHECK-NEXT:    [[Y:%.*]] = zext i1 %X to i32
350; CHECK-NEXT:    [[Z:%.*]] = shl nuw nsw i32 [[Y]], 4
351; CHECK-NEXT:    ret i32 [[Z]]
352;
353  %Y = zext i1 %X to i32
354  %Z = shl i32 %Y, 4
355  %A = and i32 %Z, 16
356  ret i32 %A
357}
358
359; Demanded bit analysis allows us to eliminate the add.
360
361define <2 x i32> @and_demanded_bits_splat_vec(<2 x i32> %x) {
362; CHECK-LABEL: @and_demanded_bits_splat_vec(
363; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> %x, <i32 7, i32 7>
364; CHECK-NEXT:    ret <2 x i32> [[Z]]
365;
366  %y = add <2 x i32> %x, <i32 8, i32 8>
367  %z = and <2 x i32> %y, <i32 7, i32 7>
368  ret <2 x i32> %z
369}
370
371; zext (x >> 8) has all zeros in the high 24-bits:  0x000000xx
372; (y | 255) has all ones in the low 8-bits: 0xyyyyyyff
373; 'and' of those is all known bits - it's just 'z'.
374
375define i32 @and_zext_demanded(i16 %x, i32 %y) {
376; CHECK-LABEL: @and_zext_demanded(
377; CHECK-NEXT:    [[S:%.*]] = lshr i16 %x, 8
378; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[S]] to i32
379; CHECK-NEXT:    ret i32 [[Z]]
380;
381  %s = lshr i16 %x, 8
382  %z = zext i16 %s to i32
383  %o = or i32 %y, 255
384  %a = and i32 %o, %z
385  ret i32 %a
386}
387
388define i32 @test32(i32 %In) {
389; CHECK-LABEL: @test32(
390; CHECK-NEXT:    ret i32 0
391;
392  %Y = and i32 %In, 16
393  %Z = lshr i32 %Y, 2
394  %A = and i32 %Z, 1
395  ret i32 %A
396}
397
398;; Code corresponding to one-bit bitfield ^1.
399define i32 @test33(i32 %b) {
400; CHECK-LABEL: @test33(
401; CHECK-NEXT:    [[TMP_13:%.*]] = xor i32 %b, 1
402; CHECK-NEXT:    ret i32 [[TMP_13]]
403;
404  %tmp.4.mask = and i32 %b, 1
405  %tmp.10 = xor i32 %tmp.4.mask, 1
406  %tmp.12 = and i32 %b, -2
407  %tmp.13 = or i32 %tmp.12, %tmp.10
408  ret i32 %tmp.13
409}
410
411define i32 @test33b(i32 %b) {
412; CHECK-LABEL: @test33b(
413; CHECK-NEXT:    [[TMP_13:%.*]] = xor i32 [[B:%.*]], 1
414; CHECK-NEXT:    ret i32 [[TMP_13]]
415;
416  %tmp.4.mask = and i32 %b, 1
417  %tmp.10 = xor i32 %tmp.4.mask, 1
418  %tmp.12 = and i32 %b, -2
419  %tmp.13 = or i32 %tmp.10, %tmp.12
420  ret i32 %tmp.13
421}
422
423define <2 x i32> @test33vec(<2 x i32> %b) {
424; CHECK-LABEL: @test33vec(
425; CHECK-NEXT:    [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
426; CHECK-NEXT:    ret <2 x i32> [[TMP_13]]
427;
428  %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1>
429  %tmp.10 = xor <2 x i32> %tmp.4.mask, <i32 1, i32 1>
430  %tmp.12 = and <2 x i32> %b, <i32 -2, i32 -2>
431  %tmp.13 = or <2 x i32> %tmp.12, %tmp.10
432  ret <2 x i32> %tmp.13
433}
434
435define <2 x i32> @test33vecb(<2 x i32> %b) {
436; CHECK-LABEL: @test33vecb(
437; CHECK-NEXT:    [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
438; CHECK-NEXT:    ret <2 x i32> [[TMP_13]]
439;
440  %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1>
441  %tmp.10 = xor <2 x i32> %tmp.4.mask, <i32 1, i32 1>
442  %tmp.12 = and <2 x i32> %b, <i32 -2, i32 -2>
443  %tmp.13 = or <2 x i32> %tmp.10, %tmp.12
444  ret <2 x i32> %tmp.13
445}
446
447define i32 @test34(i32 %A, i32 %B) {
448; CHECK-LABEL: @test34(
449; CHECK-NEXT:    ret i32 %B
450;
451  %tmp.2 = or i32 %B, %A
452  %tmp.4 = and i32 %tmp.2, %B
453  ret i32 %tmp.4
454}
455
456; FIXME: This test should only need -instsimplify (ValueTracking / computeKnownBits), not -instcombine.
457
458define <2 x i32> @PR24942(<2 x i32> %x) {
459; CHECK-LABEL: @PR24942(
460; CHECK-NEXT:    ret <2 x i32> zeroinitializer
461;
462  %lshr = lshr <2 x i32> %x, <i32 31, i32 31>
463  %and = and <2 x i32> %lshr, <i32 2, i32 2>
464  ret <2 x i32> %and
465}
466
467define i64 @test35(i32 %X) {
468; CHECK-LABEL: @test35(
469; CHECK-NEXT:  %[[sub:.*]] = sub i32 0, %X
470; CHECK-NEXT:  %[[and:.*]] = and i32 %[[sub]], 240
471; CHECK-NEXT:  %[[cst:.*]] = zext i32 %[[and]] to i64
472; CHECK-NEXT:  ret i64 %[[cst]]
473  %zext = zext i32 %X to i64
474  %zsub = sub i64 0, %zext
475  %res = and i64 %zsub, 240
476  ret i64 %res
477}
478
479define i64 @test36(i32 %X) {
480; CHECK-LABEL: @test36(
481; CHECK-NEXT:  %[[sub:.*]] = add i32 %X, 7
482; CHECK-NEXT:  %[[and:.*]] = and i32 %[[sub]], 240
483; CHECK-NEXT:  %[[cst:.*]] = zext i32 %[[and]] to i64
484; CHECK-NEXT:  ret i64 %[[cst]]
485  %zext = zext i32 %X to i64
486  %zsub = add i64 %zext, 7
487  %res = and i64 %zsub, 240
488  ret i64 %res
489}
490
491define i64 @test37(i32 %X) {
492; CHECK-LABEL: @test37(
493; CHECK-NEXT:  %[[sub:.*]] = mul i32 %X, 7
494; CHECK-NEXT:  %[[and:.*]] = and i32 %[[sub]], 240
495; CHECK-NEXT:  %[[cst:.*]] = zext i32 %[[and]] to i64
496; CHECK-NEXT:  ret i64 %[[cst]]
497  %zext = zext i32 %X to i64
498  %zsub = mul i64 %zext, 7
499  %res = and i64 %zsub, 240
500  ret i64 %res
501}
502
503define i64 @test38(i32 %X) {
504; CHECK-LABEL: @test38(
505; CHECK-NEXT:  %[[and:.*]] = and i32 %X, 240
506; CHECK-NEXT:  %[[cst:.*]] = zext i32 %[[and]] to i64
507; CHECK-NEXT:  ret i64 %[[cst]]
508  %zext = zext i32 %X to i64
509  %zsub = xor i64 %zext, 7
510  %res = and i64 %zsub, 240
511  ret i64 %res
512}
513
514define i64 @test39(i32 %X) {
515; CHECK-LABEL: @test39(
516; CHECK-NEXT:  %[[and:.*]] = and i32 %X, 240
517; CHECK-NEXT:  %[[cst:.*]] = zext i32 %[[and]] to i64
518; CHECK-NEXT:  ret i64 %[[cst]]
519  %zext = zext i32 %X to i64
520  %zsub = or i64 %zext, 7
521  %res = and i64 %zsub, 240
522  ret i64 %res
523}
524
525define i32 @test40(i1 %C) {
526; CHECK-LABEL: @test40(
527; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], i32 104, i32 10
528; CHECK-NEXT:    ret i32 [[A]]
529;
530  %A = select i1 %C, i32 1000, i32 10
531  %V = and i32 %A, 123
532  ret i32 %V
533}
534
535define <2 x i32> @test40vec(i1 %C) {
536; CHECK-LABEL: @test40vec(
537; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 104>, <2 x i32> <i32 10, i32 10>
538; CHECK-NEXT:    ret <2 x i32> [[A]]
539;
540  %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
541  %V = and <2 x i32> %A, <i32 123, i32 123>
542  ret <2 x i32> %V
543}
544
545define <2 x i32> @test40vec2(i1 %C) {
546; CHECK-LABEL: @test40vec2(
547; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 324>, <2 x i32> <i32 10, i32 12>
548; CHECK-NEXT:    ret <2 x i32> [[V]]
549;
550  %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
551  %V = and <2 x i32> %A, <i32 123, i32 333>
552  ret <2 x i32> %V
553}
554
555define i32 @test41(i1 %which) {
556; CHECK-LABEL: @test41(
557; CHECK-NEXT:  entry:
558; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
559; CHECK:       delay:
560; CHECK-NEXT:    br label [[FINAL]]
561; CHECK:       final:
562; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 104, [[ENTRY:%.*]] ], [ 10, [[DELAY]] ]
563; CHECK-NEXT:    ret i32 [[A]]
564;
565entry:
566  br i1 %which, label %final, label %delay
567
568delay:
569  br label %final
570
571final:
572  %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
573  %value = and i32 %A, 123
574  ret i32 %value
575}
576
577define <2 x i32> @test41vec(i1 %which) {
578; CHECK-LABEL: @test41vec(
579; CHECK-NEXT:  entry:
580; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
581; CHECK:       delay:
582; CHECK-NEXT:    br label [[FINAL]]
583; CHECK:       final:
584; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 104>, [[ENTRY:%.*]] ], [ <i32 10, i32 10>, [[DELAY]] ]
585; CHECK-NEXT:    ret <2 x i32> [[A]]
586;
587entry:
588  br i1 %which, label %final, label %delay
589
590delay:
591  br label %final
592
593final:
594  %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
595  %value = and <2 x i32> %A, <i32 123, i32 123>
596  ret <2 x i32> %value
597}
598
599define <2 x i32> @test41vec2(i1 %which) {
600; CHECK-LABEL: @test41vec2(
601; CHECK-NEXT:  entry:
602; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
603; CHECK:       delay:
604; CHECK-NEXT:    br label [[FINAL]]
605; CHECK:       final:
606; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 324>, [[ENTRY:%.*]] ], [ <i32 10, i32 12>, [[DELAY]] ]
607; CHECK-NEXT:    ret <2 x i32> [[A]]
608;
609entry:
610  br i1 %which, label %final, label %delay
611
612delay:
613  br label %final
614
615final:
616  %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
617  %value = and <2 x i32> %A, <i32 123, i32 333>
618  ret <2 x i32> %value
619}
620
621define i32 @test42(i32 %a, i32 %c, i32 %d) {
622; CHECK-LABEL: @test42(
623; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
624; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
625; CHECK-NEXT:    ret i32 [[AND]]
626;
627  %force = mul i32 %c, %d ; forces the complexity sorting
628  %or = or i32 %a, %force
629  %nota = xor i32 %a, -1
630  %xor = xor i32 %nota, %force
631  %and = and i32 %xor, %or
632  ret i32 %and
633}
634
635define i32 @test43(i32 %a, i32 %c, i32 %d) {
636; CHECK-LABEL: @test43(
637; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
638; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
639; CHECK-NEXT:    ret i32 [[AND]]
640;
641  %force = mul i32 %c, %d ; forces the complexity sorting
642  %or = or i32 %a, %force
643  %nota = xor i32 %a, -1
644  %xor = xor i32 %nota, %force
645  %and = and i32 %or, %xor
646  ret i32 %and
647}
648
649; (~y | x) & y -> x & y
650define i32 @test44(i32 %x, i32 %y) nounwind {
651; CHECK-LABEL: @test44(
652; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
653; CHECK-NEXT:    ret i32 [[A]]
654;
655  %n = xor i32 %y, -1
656  %o = or i32 %n, %x
657  %a = and i32 %o, %y
658  ret i32 %a
659}
660
661; (x | ~y) & y -> x & y
662define i32 @test45(i32 %x, i32 %y) nounwind {
663; CHECK-LABEL: @test45(
664; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
665; CHECK-NEXT:    ret i32 [[A]]
666;
667  %n = xor i32 %y, -1
668  %o = or i32 %x, %n
669  %a = and i32 %o, %y
670  ret i32 %a
671}
672
673; y & (~y | x) -> y | x
674define i32 @test46(i32 %x, i32 %y) nounwind {
675; CHECK-LABEL: @test46(
676; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
677; CHECK-NEXT:    ret i32 [[A]]
678;
679  %n = xor i32 %y, -1
680  %o = or i32 %n, %x
681  %a = and i32 %y, %o
682  ret i32 %a
683}
684
685; y & (x | ~y) -> y | x
686define i32 @test47(i32 %x, i32 %y) nounwind {
687; CHECK-LABEL: @test47(
688; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
689; CHECK-NEXT:    ret i32 [[A]]
690;
691  %n = xor i32 %y, -1
692  %o = or i32 %x, %n
693  %a = and i32 %y, %o
694  ret i32 %a
695}
696
697; In the next 4 tests, vary the types and predicates for extra coverage.
698; (X & (Y | ~X)) -> (X & Y), where 'not' is an inverted cmp
699
700define i1 @and_orn_cmp_1(i32 %a, i32 %b, i32 %c) {
701; CHECK-LABEL: @and_orn_cmp_1(
702; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
703; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
704; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
705; CHECK-NEXT:    ret i1 [[AND]]
706;
707  %x = icmp sgt i32 %a, %b
708  %x_inv = icmp sle i32 %a, %b
709  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
710  %or = or i1 %y, %x_inv
711  %and = and i1 %x, %or
712  ret i1 %and
713}
714
715; Commute the 'and':
716; ((Y | ~X) & X) -> (X & Y), where 'not' is an inverted cmp
717
718define <2 x i1> @and_orn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
719; CHECK-LABEL: @and_orn_cmp_2(
720; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
721; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
722; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[Y]], [[X]]
723; CHECK-NEXT:    ret <2 x i1> [[AND]]
724;
725  %x = icmp sge <2 x i32> %a, %b
726  %x_inv = icmp slt <2 x i32> %a, %b
727  %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
728  %or = or <2 x i1> %y, %x_inv
729  %and = and <2 x i1> %or, %x
730  ret <2 x i1> %and
731}
732
733; Commute the 'or':
734; (X & (~X | Y)) -> (X & Y), where 'not' is an inverted cmp
735
736define i1 @and_orn_cmp_3(i72 %a, i72 %b, i72 %c) {
737; CHECK-LABEL: @and_orn_cmp_3(
738; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
739; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
740; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
741; CHECK-NEXT:    ret i1 [[AND]]
742;
743  %x = icmp ugt i72 %a, %b
744  %x_inv = icmp ule i72 %a, %b
745  %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
746  %or = or i1 %x_inv, %y
747  %and = and i1 %x, %or
748  ret i1 %and
749}
750
751; Commute the 'and':
752; ((~X | Y) & X) -> (X & Y), where 'not' is an inverted cmp
753
754define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
755; CHECK-LABEL: @or_andn_cmp_4(
756; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
757; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
758; CHECK-NEXT:    [[AND:%.*]] = and <3 x i1> [[Y]], [[X]]
759; CHECK-NEXT:    ret <3 x i1> [[AND]]
760;
761  %x = icmp eq <3 x i32> %a, %b
762  %x_inv = icmp ne <3 x i32> %a, %b
763  %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
764  %or = or <3 x i1> %x_inv, %y
765  %and = and <3 x i1> %or, %x
766  ret <3 x i1> %and
767}
768
769; In the next 4 tests, vary the types and predicates for extra coverage.
770; (~X & (Y | X)) -> (~X & Y), where 'not' is an inverted cmp
771
772define i1 @andn_or_cmp_1(i37 %a, i37 %b, i37 %c) {
773; CHECK-LABEL: @andn_or_cmp_1(
774; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
775; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
776; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_INV]], [[Y]]
777; CHECK-NEXT:    ret i1 [[AND]]
778;
779  %x = icmp sgt i37 %a, %b
780  %x_inv = icmp sle i37 %a, %b
781  %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
782  %or = or i1 %y, %x
783  %and = and i1 %x_inv, %or
784  ret i1 %and
785}
786
787; Commute the 'and':
788; ((Y | X) & ~X) -> (~X & Y), where 'not' is an inverted cmp
789
790define i1 @andn_or_cmp_2(i16 %a, i16 %b, i16 %c) {
791; CHECK-LABEL: @andn_or_cmp_2(
792; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
793; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
794; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
795; CHECK-NEXT:    ret i1 [[AND]]
796;
797  %x = icmp sge i16 %a, %b
798  %x_inv = icmp slt i16 %a, %b
799  %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
800  %or = or i1 %y, %x
801  %and = and i1 %or, %x_inv
802  ret i1 %and
803}
804
805; Commute the 'or':
806; (~X & (X | Y)) -> (~X & Y), where 'not' is an inverted cmp
807
808define <4 x i1> @andn_or_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
809; CHECK-LABEL: @andn_or_cmp_3(
810; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
811; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
812; CHECK-NEXT:    [[AND:%.*]] = and <4 x i1> [[X_INV]], [[Y]]
813; CHECK-NEXT:    ret <4 x i1> [[AND]]
814;
815  %x = icmp ugt <4 x i32> %a, %b
816  %x_inv = icmp ule <4 x i32> %a, %b
817  %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
818  %or = or <4 x i1> %x, %y
819  %and = and <4 x i1> %x_inv, %or
820  ret <4 x i1> %and
821}
822
823; Commute the 'and':
824; ((X | Y) & ~X) -> (~X & Y), where 'not' is an inverted cmp
825
826define i1 @andn_or_cmp_4(i32 %a, i32 %b, i32 %c) {
827; CHECK-LABEL: @andn_or_cmp_4(
828; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
829; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
830; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
831; CHECK-NEXT:    ret i1 [[AND]]
832;
833  %x = icmp eq i32 %a, %b
834  %x_inv = icmp ne i32 %a, %b
835  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
836  %or = or i1 %x, %y
837  %and = and i1 %or, %x_inv
838  ret i1 %and
839}
840