1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4declare void @use8(i8)
5declare void @use32(i32)
6
7; There should be no 'and' instructions left in any test.
8
9define i32 @test1(i32 %A) {
10; CHECK-LABEL: @test1(
11; CHECK-NEXT:    ret i32 0
12;
13  %B = and i32 %A, 0
14  ret i32 %B
15}
16
17define i32 @test2(i32 %A) {
18; CHECK-LABEL: @test2(
19; CHECK-NEXT:    ret i32 [[A:%.*]]
20;
21  %B = and i32 %A, -1
22  ret i32 %B
23}
24
25define i1 @test3(i1 %A) {
26; CHECK-LABEL: @test3(
27; CHECK-NEXT:    ret i1 false
28;
29  %B = and i1 %A, false
30  ret i1 %B
31}
32
33define i1 @test4(i1 %A) {
34; CHECK-LABEL: @test4(
35; CHECK-NEXT:    ret i1 [[A:%.*]]
36;
37  %B = and i1 %A, true
38  ret i1 %B
39}
40
41define i32 @test5(i32 %A) {
42; CHECK-LABEL: @test5(
43; CHECK-NEXT:    ret i32 [[A:%.*]]
44;
45  %B = and i32 %A, %A
46  ret i32 %B
47}
48
49define i1 @test6(i1 %A) {
50; CHECK-LABEL: @test6(
51; CHECK-NEXT:    ret i1 [[A:%.*]]
52;
53  %B = and i1 %A, %A
54  ret i1 %B
55}
56
57; A & ~A == 0
58define i32 @test7(i32 %A) {
59; CHECK-LABEL: @test7(
60; CHECK-NEXT:    ret i32 0
61;
62  %NotA = xor i32 %A, -1
63  %B = and i32 %A, %NotA
64  ret i32 %B
65}
66
67; AND associates
68define i8 @test8(i8 %A) {
69; CHECK-LABEL: @test8(
70; CHECK-NEXT:    ret i8 0
71;
72  %B = and i8 %A, 3
73  %C = and i8 %B, 4
74  ret i8 %C
75}
76
77; Test of sign bit, convert to setle %A, 0
78define i1 @test9(i32 %A) {
79; CHECK-LABEL: @test9(
80; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
81; CHECK-NEXT:    ret i1 [[C]]
82;
83  %B = and i32 %A, -2147483648
84  %C = icmp ne i32 %B, 0
85  ret i1 %C
86}
87
88; Test of sign bit, convert to setle %A, 0
89define i1 @test9a(i32 %A) {
90; CHECK-LABEL: @test9a(
91; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
92; CHECK-NEXT:    ret i1 [[C]]
93;
94  %B = and i32 %A, -2147483648
95  %C = icmp ne i32 %B, 0
96  ret i1 %C
97}
98
99define i32 @test10(i32 %A) {
100; CHECK-LABEL: @test10(
101; CHECK-NEXT:    ret i32 1
102;
103  %B = and i32 %A, 12
104  %C = xor i32 %B, 15
105  ; (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
106  %D = and i32 %C, 1
107  ret i32 %D
108}
109
110define i32 @test11(i32 %A, i32* %P) {
111; CHECK-LABEL: @test11(
112; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 3
113; CHECK-NEXT:    [[C:%.*]] = xor i32 [[B]], 12
114; CHECK-NEXT:    store i32 [[C]], i32* [[P:%.*]], align 4
115; CHECK-NEXT:    ret i32 3
116;
117  %B = or i32 %A, 3
118  %C = xor i32 %B, 12
119  ; additional use of C
120  store i32 %C, i32* %P
121  ; %C = and uint %B, 3 --> 3
122  %D = and i32 %C, 3
123  ret i32 %D
124}
125
126define i1 @test12(i32 %A, i32 %B) {
127; CHECK-LABEL: @test12(
128; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
129; CHECK-NEXT:    ret i1 [[C1]]
130;
131  %C1 = icmp ult i32 %A, %B
132  %C2 = icmp ule i32 %A, %B
133  ; (A < B) & (A <= B) === (A < B)
134  %D = and i1 %C1, %C2
135  ret i1 %D
136}
137
138define i1 @test13(i32 %A, i32 %B) {
139; CHECK-LABEL: @test13(
140; CHECK-NEXT:    ret i1 false
141;
142  %C1 = icmp ult i32 %A, %B
143  %C2 = icmp ugt i32 %A, %B
144  ; (A < B) & (A > B) === false
145  %D = and i1 %C1, %C2
146  ret i1 %D
147}
148
149define i1 @test14(i8 %A) {
150; CHECK-LABEL: @test14(
151; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], 0
152; CHECK-NEXT:    ret i1 [[C]]
153;
154  %B = and i8 %A, -128
155  %C = icmp ne i8 %B, 0
156  ret i1 %C
157}
158
159define i8 @test15(i8 %A) {
160; CHECK-LABEL: @test15(
161; CHECK-NEXT:    ret i8 0
162;
163  %B = lshr i8 %A, 7
164  ; Always equals zero
165  %C = and i8 %B, 2
166  ret i8 %C
167}
168
169define i8 @test16(i8 %A) {
170; CHECK-LABEL: @test16(
171; CHECK-NEXT:    ret i8 0
172;
173  %B = shl i8 %A, 2
174  %C = and i8 %B, 3
175  ret i8 %C
176}
177
178define i1 @test18(i32 %A) {
179; CHECK-LABEL: @test18(
180; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A:%.*]], 127
181; CHECK-NEXT:    ret i1 [[C]]
182;
183  %B = and i32 %A, -128
184  ;; C >= 128
185  %C = icmp ne i32 %B, 0
186  ret i1 %C
187}
188
189define <2 x i1> @test18_vec(<2 x i32> %A) {
190; CHECK-LABEL: @test18_vec(
191; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 127, i32 127>
192; CHECK-NEXT:    ret <2 x i1> [[C]]
193;
194  %B = and <2 x i32> %A, <i32 -128, i32 -128>
195  %C = icmp ne <2 x i32> %B, zeroinitializer
196  ret <2 x i1> %C
197}
198
199define i1 @test18a(i8 %A) {
200; CHECK-LABEL: @test18a(
201; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A:%.*]], 2
202; CHECK-NEXT:    ret i1 [[C]]
203;
204  %B = and i8 %A, -2
205  %C = icmp eq i8 %B, 0
206  ret i1 %C
207}
208
209define <2 x i1> @test18a_vec(<2 x i8> %A) {
210; CHECK-LABEL: @test18a_vec(
211; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], <i8 2, i8 2>
212; CHECK-NEXT:    ret <2 x i1> [[C]]
213;
214  %B = and <2 x i8> %A, <i8 -2, i8 -2>
215  %C = icmp eq <2 x i8> %B, zeroinitializer
216  ret <2 x i1> %C
217}
218
219define i32 @test19(i32 %A) {
220; CHECK-LABEL: @test19(
221; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 3
222; CHECK-NEXT:    ret i32 [[B]]
223;
224  %B = shl i32 %A, 3
225  ;; Clearing a zero bit
226  %C = and i32 %B, -2
227  ret i32 %C
228}
229
230define i8 @test20(i8 %A) {
231; CHECK-LABEL: @test20(
232; CHECK-NEXT:    [[C:%.*]] = lshr i8 [[A:%.*]], 7
233; CHECK-NEXT:    ret i8 [[C]]
234;
235  %C = lshr i8 %A, 7
236  ;; Unneeded
237  %D = and i8 %C, 1
238  ret i8 %D
239}
240
241define i1 @test23(i32 %A) {
242; CHECK-LABEL: @test23(
243; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], 2
244; CHECK-NEXT:    ret i1 [[TMP1]]
245;
246  %B = icmp sgt i32 %A, 1
247  %C = icmp sle i32 %A, 2
248  %D = and i1 %B, %C
249  ret i1 %D
250}
251
252; FIXME: Vectors should fold too.
253define <2 x i1> @test23vec(<2 x i32> %A) {
254; CHECK-LABEL: @test23vec(
255; CHECK-NEXT:    [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 1, i32 1>
256; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 3, i32 3>
257; CHECK-NEXT:    [[D:%.*]] = and <2 x i1> [[B]], [[C]]
258; CHECK-NEXT:    ret <2 x i1> [[D]]
259;
260  %B = icmp sgt <2 x i32> %A, <i32 1, i32 1>
261  %C = icmp sle <2 x i32> %A, <i32 2, i32 2>
262  %D = and <2 x i1> %B, %C
263  ret <2 x i1> %D
264}
265
266define i1 @test24(i32 %A) {
267; CHECK-LABEL: @test24(
268; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 2
269; CHECK-NEXT:    ret i1 [[TMP1]]
270;
271  %B = icmp sgt i32 %A, 1
272  %C = icmp ne i32 %A, 2
273  ;; A > 2
274  %D = and i1 %B, %C
275  ret i1 %D
276}
277
278define i1 @test25(i32 %A) {
279; CHECK-LABEL: @test25(
280; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
281; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 50
282; CHECK-NEXT:    ret i1 [[TMP1]]
283;
284  %B = icmp sge i32 %A, 50
285  %C = icmp slt i32 %A, 100
286  %D = and i1 %B, %C
287  ret i1 %D
288}
289
290; FIXME: Vectors should fold too.
291define <2 x i1> @test25vec(<2 x i32> %A) {
292; CHECK-LABEL: @test25vec(
293; CHECK-NEXT:    [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 49, i32 49>
294; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 100, i32 100>
295; CHECK-NEXT:    [[D:%.*]] = and <2 x i1> [[B]], [[C]]
296; CHECK-NEXT:    ret <2 x i1> [[D]]
297;
298  %B = icmp sge <2 x i32> %A, <i32 50, i32 50>
299  %C = icmp slt <2 x i32> %A, <i32 100, i32 100>
300  %D = and <2 x i1> %B, %C
301  ret <2 x i1> %D
302}
303
304define i8 @test27(i8 %A) {
305; CHECK-LABEL: @test27(
306; CHECK-NEXT:    ret i8 0
307;
308  %B = and i8 %A, 4
309  %C = sub i8 %B, 16
310  ;; 0xF0
311  %D = and i8 %C, -16
312  %E = add i8 %D, 16
313  ret i8 %E
314}
315
316;; This is just a zero-extending shr.
317define i32 @test28(i32 %X) {
318; CHECK-LABEL: @test28(
319; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 24
320; CHECK-NEXT:    ret i32 [[TMP1]]
321;
322  ;; Sign extend
323  %Y = ashr i32 %X, 24
324  ;; Mask out sign bits
325  %Z = and i32 %Y, 255
326  ret i32 %Z
327}
328
329define i32 @test29(i8 %X) {
330; CHECK-LABEL: @test29(
331; CHECK-NEXT:    [[Y:%.*]] = zext i8 [[X:%.*]] to i32
332; CHECK-NEXT:    ret i32 [[Y]]
333;
334  %Y = zext i8 %X to i32
335  ;; Zero extend makes this unneeded.
336  %Z = and i32 %Y, 255
337  ret i32 %Z
338}
339
340define i32 @test30(i1 %X) {
341; CHECK-LABEL: @test30(
342; CHECK-NEXT:    [[Y:%.*]] = zext i1 [[X:%.*]] to i32
343; CHECK-NEXT:    ret i32 [[Y]]
344;
345  %Y = zext i1 %X to i32
346  %Z = and i32 %Y, 1
347  ret i32 %Z
348}
349
350define i32 @test31(i1 %X) {
351; CHECK-LABEL: @test31(
352; CHECK-NEXT:    [[Z:%.*]] = select i1 [[X:%.*]], i32 16, i32 0
353; CHECK-NEXT:    ret i32 [[Z]]
354;
355  %Y = zext i1 %X to i32
356  %Z = shl i32 %Y, 4
357  %A = and i32 %Z, 16
358  ret i32 %A
359}
360
361; Demanded bit analysis allows us to eliminate the add.
362
363define <2 x i32> @and_demanded_bits_splat_vec(<2 x i32> %x) {
364; CHECK-LABEL: @and_demanded_bits_splat_vec(
365; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> [[X:%.*]], <i32 7, i32 7>
366; CHECK-NEXT:    ret <2 x i32> [[Z]]
367;
368  %y = add <2 x i32> %x, <i32 8, i32 8>
369  %z = and <2 x i32> %y, <i32 7, i32 7>
370  ret <2 x i32> %z
371}
372
373; zext (x >> 8) has all zeros in the high 24-bits:  0x000000xx
374; (y | 255) has all ones in the low 8-bits: 0xyyyyyyff
375; 'and' of those is all known bits - it's just 'z'.
376
377define i32 @and_zext_demanded(i16 %x, i32 %y) {
378; CHECK-LABEL: @and_zext_demanded(
379; CHECK-NEXT:    [[S:%.*]] = lshr i16 [[X:%.*]], 8
380; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[S]] to i32
381; CHECK-NEXT:    ret i32 [[Z]]
382;
383  %s = lshr i16 %x, 8
384  %z = zext i16 %s to i32
385  %o = or i32 %y, 255
386  %a = and i32 %o, %z
387  ret i32 %a
388}
389
390define i32 @test32(i32 %In) {
391; CHECK-LABEL: @test32(
392; CHECK-NEXT:    ret i32 0
393;
394  %Y = and i32 %In, 16
395  %Z = lshr i32 %Y, 2
396  %A = and i32 %Z, 1
397  ret i32 %A
398}
399
400;; Code corresponding to one-bit bitfield ^1.
401define i32 @test33(i32 %b) {
402; CHECK-LABEL: @test33(
403; CHECK-NEXT:    [[T13:%.*]] = xor i32 [[B:%.*]], 1
404; CHECK-NEXT:    ret i32 [[T13]]
405;
406  %t4.mask = and i32 %b, 1
407  %t10 = xor i32 %t4.mask, 1
408  %t12 = and i32 %b, -2
409  %t13 = or i32 %t12, %t10
410  ret i32 %t13
411}
412
413define i32 @test33b(i32 %b) {
414; CHECK-LABEL: @test33b(
415; CHECK-NEXT:    [[T13:%.*]] = xor i32 [[B:%.*]], 1
416; CHECK-NEXT:    ret i32 [[T13]]
417;
418  %t4.mask = and i32 %b, 1
419  %t10 = xor i32 %t4.mask, 1
420  %t12 = and i32 %b, -2
421  %t13 = or i32 %t10, %t12
422  ret i32 %t13
423}
424
425define <2 x i32> @test33vec(<2 x i32> %b) {
426; CHECK-LABEL: @test33vec(
427; CHECK-NEXT:    [[T13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
428; CHECK-NEXT:    ret <2 x i32> [[T13]]
429;
430  %t4.mask = and <2 x i32> %b, <i32 1, i32 1>
431  %t10 = xor <2 x i32> %t4.mask, <i32 1, i32 1>
432  %t12 = and <2 x i32> %b, <i32 -2, i32 -2>
433  %t13 = or <2 x i32> %t12, %t10
434  ret <2 x i32> %t13
435}
436
437define <2 x i32> @test33vecb(<2 x i32> %b) {
438; CHECK-LABEL: @test33vecb(
439; CHECK-NEXT:    [[T13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
440; CHECK-NEXT:    ret <2 x i32> [[T13]]
441;
442  %t4.mask = and <2 x i32> %b, <i32 1, i32 1>
443  %t10 = xor <2 x i32> %t4.mask, <i32 1, i32 1>
444  %t12 = and <2 x i32> %b, <i32 -2, i32 -2>
445  %t13 = or <2 x i32> %t10, %t12
446  ret <2 x i32> %t13
447}
448
449define i32 @test34(i32 %A, i32 %B) {
450; CHECK-LABEL: @test34(
451; CHECK-NEXT:    ret i32 [[B:%.*]]
452;
453  %t2 = or i32 %B, %A
454  %t4 = and i32 %t2, %B
455  ret i32 %t4
456}
457
458; FIXME: This test should only need -instsimplify (ValueTracking / computeKnownBits), not -instcombine.
459
460define <2 x i32> @PR24942(<2 x i32> %x) {
461; CHECK-LABEL: @PR24942(
462; CHECK-NEXT:    ret <2 x i32> zeroinitializer
463;
464  %lshr = lshr <2 x i32> %x, <i32 31, i32 31>
465  %and = and <2 x i32> %lshr, <i32 2, i32 2>
466  ret <2 x i32> %and
467}
468
469define i64 @test35(i32 %X) {
470; CHECK-LABEL: @test35(
471; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
472; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
473; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
474; CHECK-NEXT:    ret i64 [[RES]]
475;
476  %zext = zext i32 %X to i64
477  %zsub = sub i64 0, %zext
478  %res = and i64 %zsub, 240
479  ret i64 %res
480}
481
482define <2 x i64> @test35_uniform(<2 x i32> %X) {
483; CHECK-LABEL: @test35_uniform(
484; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>
485; CHECK-NEXT:    [[ZSUB:%.*]] = sub nsw <2 x i64> zeroinitializer, [[ZEXT]]
486; CHECK-NEXT:    [[RES:%.*]] = and <2 x i64> [[ZSUB]], <i64 240, i64 240>
487; CHECK-NEXT:    ret <2 x i64> [[RES]]
488;
489  %zext = zext <2 x i32> %X to <2 x i64>
490  %zsub = sub <2 x i64> zeroinitializer, %zext
491  %res = and <2 x i64> %zsub, <i64 240, i64 240>
492  ret <2 x i64> %res
493}
494
495define i64 @test36(i32 %X) {
496; CHECK-LABEL: @test36(
497; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
498; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
499; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
500; CHECK-NEXT:    ret i64 [[RES]]
501;
502  %zext = zext i32 %X to i64
503  %zsub = add i64 %zext, 7
504  %res = and i64 %zsub, 240
505  ret i64 %res
506}
507
508define <2 x i64> @test36_undef(<2 x i32> %X) {
509; CHECK-LABEL: @test36_undef(
510; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>
511; CHECK-NEXT:    [[ZSUB:%.*]] = add <2 x i64> [[ZEXT]], <i64 7, i64 undef>
512; CHECK-NEXT:    [[RES:%.*]] = and <2 x i64> [[ZSUB]], <i64 240, i64 undef>
513; CHECK-NEXT:    ret <2 x i64> [[RES]]
514;
515  %zext = zext <2 x i32> %X to <2 x i64>
516  %zsub = add <2 x i64> %zext, <i64 7, i64 undef>
517  %res = and <2 x i64> %zsub, <i64 240, i64 undef>
518  ret <2 x i64> %res
519}
520
521define i64 @test37(i32 %X) {
522; CHECK-LABEL: @test37(
523; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], 7
524; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
525; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
526; CHECK-NEXT:    ret i64 [[RES]]
527;
528  %zext = zext i32 %X to i64
529  %zsub = mul i64 %zext, 7
530  %res = and i64 %zsub, 240
531  ret i64 %res
532}
533
534define <2 x i64> @test37_nonuniform(<2 x i32> %X) {
535; CHECK-LABEL: @test37_nonuniform(
536; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>
537; CHECK-NEXT:    [[ZSUB:%.*]] = mul nuw nsw <2 x i64> [[ZEXT]], <i64 7, i64 9>
538; CHECK-NEXT:    [[RES:%.*]] = and <2 x i64> [[ZSUB]], <i64 240, i64 110>
539; CHECK-NEXT:    ret <2 x i64> [[RES]]
540;
541  %zext = zext <2 x i32> %X to <2 x i64>
542  %zsub = mul <2 x i64> %zext, <i64 7, i64 9>
543  %res = and <2 x i64> %zsub, <i64 240, i64 110>
544  ret <2 x i64> %res
545}
546
547define i64 @test38(i32 %X) {
548; CHECK-LABEL: @test38(
549; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
550; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP1]] to i64
551; CHECK-NEXT:    ret i64 [[RES]]
552;
553  %zext = zext i32 %X to i64
554  %zsub = xor i64 %zext, 7
555  %res = and i64 %zsub, 240
556  ret i64 %res
557}
558
559define i64 @test39(i32 %X) {
560; CHECK-LABEL: @test39(
561; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
562; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP1]] to i64
563; CHECK-NEXT:    ret i64 [[RES]]
564;
565  %zext = zext i32 %X to i64
566  %zsub = or i64 %zext, 7
567  %res = and i64 %zsub, 240
568  ret i64 %res
569}
570
571define i32 @test40(i1 %C) {
572; CHECK-LABEL: @test40(
573; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], i32 104, i32 10
574; CHECK-NEXT:    ret i32 [[A]]
575;
576  %A = select i1 %C, i32 1000, i32 10
577  %V = and i32 %A, 123
578  ret i32 %V
579}
580
581define <2 x i32> @test40vec(i1 %C) {
582; CHECK-LABEL: @test40vec(
583; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 104>, <2 x i32> <i32 10, i32 10>
584; CHECK-NEXT:    ret <2 x i32> [[A]]
585;
586  %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
587  %V = and <2 x i32> %A, <i32 123, i32 123>
588  ret <2 x i32> %V
589}
590
591define <2 x i32> @test40vec2(i1 %C) {
592; CHECK-LABEL: @test40vec2(
593; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 324>, <2 x i32> <i32 10, i32 12>
594; CHECK-NEXT:    ret <2 x i32> [[V]]
595;
596  %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
597  %V = and <2 x i32> %A, <i32 123, i32 333>
598  ret <2 x i32> %V
599}
600
601define i32 @test41(i1 %which) {
602; CHECK-LABEL: @test41(
603; CHECK-NEXT:  entry:
604; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
605; CHECK:       delay:
606; CHECK-NEXT:    br label [[FINAL]]
607; CHECK:       final:
608; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 104, [[ENTRY:%.*]] ], [ 10, [[DELAY]] ]
609; CHECK-NEXT:    ret i32 [[A]]
610;
611entry:
612  br i1 %which, label %final, label %delay
613
614delay:
615  br label %final
616
617final:
618  %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
619  %value = and i32 %A, 123
620  ret i32 %value
621}
622
623define <2 x i32> @test41vec(i1 %which) {
624; CHECK-LABEL: @test41vec(
625; CHECK-NEXT:  entry:
626; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
627; CHECK:       delay:
628; CHECK-NEXT:    br label [[FINAL]]
629; CHECK:       final:
630; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 104>, [[ENTRY:%.*]] ], [ <i32 10, i32 10>, [[DELAY]] ]
631; CHECK-NEXT:    ret <2 x i32> [[A]]
632;
633entry:
634  br i1 %which, label %final, label %delay
635
636delay:
637  br label %final
638
639final:
640  %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
641  %value = and <2 x i32> %A, <i32 123, i32 123>
642  ret <2 x i32> %value
643}
644
645define <2 x i32> @test41vec2(i1 %which) {
646; CHECK-LABEL: @test41vec2(
647; CHECK-NEXT:  entry:
648; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
649; CHECK:       delay:
650; CHECK-NEXT:    br label [[FINAL]]
651; CHECK:       final:
652; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 324>, [[ENTRY:%.*]] ], [ <i32 10, i32 12>, [[DELAY]] ]
653; CHECK-NEXT:    ret <2 x i32> [[A]]
654;
655entry:
656  br i1 %which, label %final, label %delay
657
658delay:
659  br label %final
660
661final:
662  %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
663  %value = and <2 x i32> %A, <i32 123, i32 333>
664  ret <2 x i32> %value
665}
666
667define i32 @test42(i32 %a, i32 %c, i32 %d) {
668; CHECK-LABEL: @test42(
669; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
670; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
671; CHECK-NEXT:    ret i32 [[AND]]
672;
673  %force = mul i32 %c, %d ; forces the complexity sorting
674  %or = or i32 %a, %force
675  %nota = xor i32 %a, -1
676  %xor = xor i32 %nota, %force
677  %and = and i32 %xor, %or
678  ret i32 %and
679}
680
681define i32 @test43(i32 %a, i32 %c, i32 %d) {
682; CHECK-LABEL: @test43(
683; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
684; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
685; CHECK-NEXT:    ret i32 [[AND]]
686;
687  %force = mul i32 %c, %d ; forces the complexity sorting
688  %or = or i32 %a, %force
689  %nota = xor i32 %a, -1
690  %xor = xor i32 %nota, %force
691  %and = and i32 %or, %xor
692  ret i32 %and
693}
694
695; (~y | x) & y -> x & y
696define i32 @test44(i32 %x, i32 %y) nounwind {
697; CHECK-LABEL: @test44(
698; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
699; CHECK-NEXT:    ret i32 [[A]]
700;
701  %n = xor i32 %y, -1
702  %o = or i32 %n, %x
703  %a = and i32 %o, %y
704  ret i32 %a
705}
706
707; (x | ~y) & y -> x & y
708define i32 @test45(i32 %x, i32 %y) nounwind {
709; CHECK-LABEL: @test45(
710; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
711; CHECK-NEXT:    ret i32 [[A]]
712;
713  %n = xor i32 %y, -1
714  %o = or i32 %x, %n
715  %a = and i32 %o, %y
716  ret i32 %a
717}
718
719; y & (~y | x) -> y | x
720define i32 @test46(i32 %x, i32 %y) nounwind {
721; CHECK-LABEL: @test46(
722; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
723; CHECK-NEXT:    ret i32 [[A]]
724;
725  %n = xor i32 %y, -1
726  %o = or i32 %n, %x
727  %a = and i32 %y, %o
728  ret i32 %a
729}
730
731; y & (x | ~y) -> y | x
732define i32 @test47(i32 %x, i32 %y) nounwind {
733; CHECK-LABEL: @test47(
734; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
735; CHECK-NEXT:    ret i32 [[A]]
736;
737  %n = xor i32 %y, -1
738  %o = or i32 %x, %n
739  %a = and i32 %y, %o
740  ret i32 %a
741}
742
743; In the next 4 tests, vary the types and predicates for extra coverage.
744; (X & (Y | ~X)) -> (X & Y), where 'not' is an inverted cmp
745
746define i1 @and_orn_cmp_1(i32 %a, i32 %b, i32 %c) {
747; CHECK-LABEL: @and_orn_cmp_1(
748; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
749; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
750; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
751; CHECK-NEXT:    ret i1 [[AND]]
752;
753  %x = icmp sgt i32 %a, %b
754  %x_inv = icmp sle i32 %a, %b
755  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
756  %or = or i1 %y, %x_inv
757  %and = and i1 %x, %or
758  ret i1 %and
759}
760
761; Commute the 'and':
762; ((Y | ~X) & X) -> (X & Y), where 'not' is an inverted cmp
763
764define <2 x i1> @and_orn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
765; CHECK-LABEL: @and_orn_cmp_2(
766; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
767; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
768; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[Y]], [[X]]
769; CHECK-NEXT:    ret <2 x i1> [[AND]]
770;
771  %x = icmp sge <2 x i32> %a, %b
772  %x_inv = icmp slt <2 x i32> %a, %b
773  %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
774  %or = or <2 x i1> %y, %x_inv
775  %and = and <2 x i1> %or, %x
776  ret <2 x i1> %and
777}
778
779; Commute the 'or':
780; (X & (~X | Y)) -> (X & Y), where 'not' is an inverted cmp
781
782define i1 @and_orn_cmp_3(i72 %a, i72 %b, i72 %c) {
783; CHECK-LABEL: @and_orn_cmp_3(
784; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
785; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
786; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
787; CHECK-NEXT:    ret i1 [[AND]]
788;
789  %x = icmp ugt i72 %a, %b
790  %x_inv = icmp ule i72 %a, %b
791  %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
792  %or = or i1 %x_inv, %y
793  %and = and i1 %x, %or
794  ret i1 %and
795}
796
797; Commute the 'and':
798; ((~X | Y) & X) -> (X & Y), where 'not' is an inverted cmp
799
800define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
801; CHECK-LABEL: @or_andn_cmp_4(
802; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
803; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
804; CHECK-NEXT:    [[AND:%.*]] = and <3 x i1> [[Y]], [[X]]
805; CHECK-NEXT:    ret <3 x i1> [[AND]]
806;
807  %x = icmp eq <3 x i32> %a, %b
808  %x_inv = icmp ne <3 x i32> %a, %b
809  %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
810  %or = or <3 x i1> %x_inv, %y
811  %and = and <3 x i1> %or, %x
812  ret <3 x i1> %and
813}
814
815; In the next 4 tests, vary the types and predicates for extra coverage.
816; (~X & (Y | X)) -> (~X & Y), where 'not' is an inverted cmp
817
818define i1 @andn_or_cmp_1(i37 %a, i37 %b, i37 %c) {
819; CHECK-LABEL: @andn_or_cmp_1(
820; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
821; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
822; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_INV]], [[Y]]
823; CHECK-NEXT:    ret i1 [[AND]]
824;
825  %x = icmp sgt i37 %a, %b
826  %x_inv = icmp sle i37 %a, %b
827  %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
828  %or = or i1 %y, %x
829  %and = and i1 %x_inv, %or
830  ret i1 %and
831}
832
833; Commute the 'and':
834; ((Y | X) & ~X) -> (~X & Y), where 'not' is an inverted cmp
835
836define i1 @andn_or_cmp_2(i16 %a, i16 %b, i16 %c) {
837; CHECK-LABEL: @andn_or_cmp_2(
838; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
839; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
840; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
841; CHECK-NEXT:    ret i1 [[AND]]
842;
843  %x = icmp sge i16 %a, %b
844  %x_inv = icmp slt i16 %a, %b
845  %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
846  %or = or i1 %y, %x
847  %and = and i1 %or, %x_inv
848  ret i1 %and
849}
850
851; Commute the 'or':
852; (~X & (X | Y)) -> (~X & Y), where 'not' is an inverted cmp
853
854define <4 x i1> @andn_or_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
855; CHECK-LABEL: @andn_or_cmp_3(
856; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
857; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
858; CHECK-NEXT:    [[AND:%.*]] = and <4 x i1> [[X_INV]], [[Y]]
859; CHECK-NEXT:    ret <4 x i1> [[AND]]
860;
861  %x = icmp ugt <4 x i32> %a, %b
862  %x_inv = icmp ule <4 x i32> %a, %b
863  %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
864  %or = or <4 x i1> %x, %y
865  %and = and <4 x i1> %x_inv, %or
866  ret <4 x i1> %and
867}
868
869; Commute the 'and':
870; ((X | Y) & ~X) -> (~X & Y), where 'not' is an inverted cmp
871
872define i1 @andn_or_cmp_4(i32 %a, i32 %b, i32 %c) {
873; CHECK-LABEL: @andn_or_cmp_4(
874; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
875; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
876; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
877; CHECK-NEXT:    ret i1 [[AND]]
878;
879  %x = icmp eq i32 %a, %b
880  %x_inv = icmp ne i32 %a, %b
881  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
882  %or = or i1 %x, %y
883  %and = and i1 %or, %x_inv
884  ret i1 %and
885}
886
887define i32 @lowbitmask_casted_shift(i8 %x) {
888; CHECK-LABEL: @lowbitmask_casted_shift(
889; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
890; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[TMP1]], 1
891; CHECK-NEXT:    ret i32 [[R]]
892;
893  %a = ashr i8 %x, 1
894  %s = sext i8 %a to i32
895  %r = and i32 %s, 2147483647
896  ret i32 %r
897}
898
899; Negative test - mask constant is too big.
900
901define i32 @lowbitmask_casted_shift_wrong_mask1(i8 %x) {
902; CHECK-LABEL: @lowbitmask_casted_shift_wrong_mask1(
903; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 2
904; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
905; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 2147483647
906; CHECK-NEXT:    ret i32 [[R]]
907;
908  %a = ashr i8 %x, 2
909  %s = sext i8 %a to i32
910  %r = and i32 %s, 2147483647 ; 0x7fffffff
911  ret i32 %r
912}
913
914; Negative test - mask constant is too small.
915
916define i32 @lowbitmask_casted_shift_wrong_mask2(i8 %x) {
917; CHECK-LABEL: @lowbitmask_casted_shift_wrong_mask2(
918; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 2
919; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
920; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 536870911
921; CHECK-NEXT:    ret i32 [[R]]
922;
923  %a = ashr i8 %x, 2
924  %s = sext i8 %a to i32
925  %r = and i32 %s, 536870911  ; 0x1fffffff
926  ret i32 %r
927}
928
929; Extra use of shift is ok.
930
931define i32 @lowbitmask_casted_shift_use1(i8 %x) {
932; CHECK-LABEL: @lowbitmask_casted_shift_use1(
933; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 3
934; CHECK-NEXT:    call void @use8(i8 [[A]])
935; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
936; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[TMP1]], 3
937; CHECK-NEXT:    ret i32 [[R]]
938;
939  %a = ashr i8 %x, 3
940  call void @use8(i8 %a)
941  %s = sext i8 %a to i32
942  %r = and i32 %s, 536870911
943  ret i32 %r
944}
945
946; Negative test - extra use of sext requires more instructions.
947
948define i32 @lowbitmask_casted_shift_use2(i8 %x) {
949; CHECK-LABEL: @lowbitmask_casted_shift_use2(
950; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 3
951; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
952; CHECK-NEXT:    call void @use32(i32 [[S]])
953; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 536870911
954; CHECK-NEXT:    ret i32 [[R]]
955;
956  %a = ashr i8 %x, 3
957  %s = sext i8 %a to i32
958  call void @use32(i32 %s)
959  %r = and i32 %s, 536870911
960  ret i32 %r
961}
962
963; Vectors/weird types are ok.
964
965define <2 x i59> @lowbitmask_casted_shift_vec_splat(<2 x i47> %x) {
966; CHECK-LABEL: @lowbitmask_casted_shift_vec_splat(
967; CHECK-NEXT:    [[TMP1:%.*]] = sext <2 x i47> [[X:%.*]] to <2 x i59>
968; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i59> [[TMP1]], <i59 5, i59 5>
969; CHECK-NEXT:    ret <2 x i59> [[R]]
970;
971  %a = ashr <2 x i47> %x, <i47 5, i47 5>
972  %s = sext <2 x i47> %a to <2 x i59>
973  %r = and <2 x i59> %s, <i59 18014398509481983, i59 18014398509481983>  ;  -1 u>> 5 == 0x3f_ffff_ffff_ffff
974  ret <2 x i59> %r
975}
976
977define i32 @lowmask_sext_in_reg(i32 %x) {
978; CHECK-LABEL: @lowmask_sext_in_reg(
979; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
980; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 20
981; CHECK-NEXT:    call void @use32(i32 [[R]])
982; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], 4095
983; CHECK-NEXT:    ret i32 [[AND]]
984;
985  %l = shl i32 %x, 20
986  %r = ashr i32 %l, 20
987  call void @use32(i32 %r)
988  %and = and i32 %r, 4095
989  ret i32 %and
990}
991
992; Negative test - mismatched shift amounts
993
994define i32 @lowmask_not_sext_in_reg(i32 %x) {
995; CHECK-LABEL: @lowmask_not_sext_in_reg(
996; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 19
997; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[L]], 20
998; CHECK-NEXT:    call void @use32(i32 [[R]])
999; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
1000; CHECK-NEXT:    ret i32 [[AND]]
1001;
1002  %l = shl i32 %x, 19
1003  %r = ashr i32 %l, 20
1004  call void @use32(i32 %r)
1005  %and = and i32 %r, 4095
1006  ret i32 %and
1007}
1008
1009; Negative test - too much shift for mask
1010
1011define i32 @not_lowmask_sext_in_reg(i32 %x) {
1012; CHECK-LABEL: @not_lowmask_sext_in_reg(
1013; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
1014; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 20
1015; CHECK-NEXT:    call void @use32(i32 [[R]])
1016; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4096
1017; CHECK-NEXT:    ret i32 [[AND]]
1018;
1019  %l = shl i32 %x, 20
1020  %r = ashr i32 %l, 20
1021  call void @use32(i32 %r)
1022  %and = and i32 %r, 4096
1023  ret i32 %and
1024}
1025
1026; Negative test - too much shift for mask
1027
1028define i32 @not_lowmask_sext_in_reg2(i32 %x) {
1029; CHECK-LABEL: @not_lowmask_sext_in_reg2(
1030; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 21
1031; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 21
1032; CHECK-NEXT:    call void @use32(i32 [[R]])
1033; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
1034; CHECK-NEXT:    ret i32 [[AND]]
1035;
1036  %l = shl i32 %x, 21
1037  %r = ashr i32 %l, 21
1038  call void @use32(i32 %r)
1039  %and = and i32 %r, 4095
1040  ret i32 %and
1041}
1042
1043define <2 x i32> @lowmask_sext_in_reg_splat(<2 x i32> %x, <2 x i32>* %p) {
1044; CHECK-LABEL: @lowmask_sext_in_reg_splat(
1045; CHECK-NEXT:    [[L:%.*]] = shl <2 x i32> [[X:%.*]], <i32 20, i32 20>
1046; CHECK-NEXT:    [[R:%.*]] = ashr exact <2 x i32> [[L]], <i32 20, i32 20>
1047; CHECK-NEXT:    store <2 x i32> [[R]], <2 x i32>* [[P:%.*]], align 8
1048; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X]], <i32 4095, i32 4095>
1049; CHECK-NEXT:    ret <2 x i32> [[AND]]
1050;
1051  %l = shl <2 x i32> %x, <i32 20, i32 20>
1052  %r = ashr <2 x i32> %l, <i32 20, i32 20>
1053  store <2 x i32> %r, <2 x i32>* %p
1054  %and = and <2 x i32> %r, <i32 4095, i32 4095>
1055  ret <2 x i32> %and
1056}
1057
1058define i8 @lowmask_add(i8 %x) {
1059; CHECK-LABEL: @lowmask_add(
1060; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1061; CHECK-NEXT:    call void @use8(i8 [[A]])
1062; CHECK-NEXT:    [[R:%.*]] = and i8 [[X]], 32
1063; CHECK-NEXT:    ret i8 [[R]]
1064;
1065  %a = add i8 %x, -64 ; 0xc0
1066  call void @use8(i8 %a)
1067  %r = and i8 %a, 32 ; 0x20
1068  ret i8 %r
1069}
1070
1071define i8 @lowmask_add_2(i8 %x) {
1072; CHECK-LABEL: @lowmask_add_2(
1073; CHECK-NEXT:    [[R:%.*]] = and i8 [[X:%.*]], 63
1074; CHECK-NEXT:    ret i8 [[R]]
1075;
1076  %a = add i8 %x, -64 ; 0xc0
1077  %r = and i8 %a, 63 ; 0x3f
1078  ret i8 %r
1079}
1080
1081define i8 @lowmask_add_2_uses(i8 %x) {
1082; CHECK-LABEL: @lowmask_add_2_uses(
1083; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1084; CHECK-NEXT:    call void @use8(i8 [[A]])
1085; CHECK-NEXT:    [[R:%.*]] = and i8 [[X]], 63
1086; CHECK-NEXT:    ret i8 [[R]]
1087;
1088  %a = add i8 %x, -64 ; 0xc0
1089  call void @use8(i8 %a)
1090  %r = and i8 %a, 63 ; 0x3f
1091  ret i8 %r
1092}
1093
1094define <2 x i8> @lowmask_add_2_splat(<2 x i8> %x, <2 x i8>* %p) {
1095; CHECK-LABEL: @lowmask_add_2_splat(
1096; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
1097; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1098; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[X]], <i8 63, i8 63>
1099; CHECK-NEXT:    ret <2 x i8> [[R]]
1100;
1101  %a = add <2 x i8> %x, <i8 -64, i8 -64> ; 0xc0
1102  store <2 x i8> %a, <2 x i8>* %p
1103  %r = and <2 x i8> %a, <i8 63, i8 63> ; 0x3f
1104  ret <2 x i8> %r
1105}
1106
1107; Negative test - mask overlaps low bit of add
1108
1109define i8 @not_lowmask_add(i8 %x) {
1110; CHECK-LABEL: @not_lowmask_add(
1111; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1112; CHECK-NEXT:    call void @use8(i8 [[A]])
1113; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], 64
1114; CHECK-NEXT:    ret i8 [[R]]
1115;
1116  %a = add i8 %x, -64 ; 0xc0
1117  call void @use8(i8 %a)
1118  %r = and i8 %a, 64 ; 0x40
1119  ret i8 %r
1120}
1121
1122; Negative test - mask overlaps low bit of add
1123
1124define i8 @not_lowmask_add2(i8 %x) {
1125; CHECK-LABEL: @not_lowmask_add2(
1126; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -96
1127; CHECK-NEXT:    call void @use8(i8 [[A]])
1128; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], 63
1129; CHECK-NEXT:    ret i8 [[R]]
1130;
1131  %a = add i8 %x, -96 ; 0xe0
1132  call void @use8(i8 %a)
1133  %r = and i8 %a, 63 ; 0x3f
1134  ret i8 %r
1135}
1136
1137define <2 x i8> @lowmask_add_splat(<2 x i8> %x, <2 x i8>* %p) {
1138; CHECK-LABEL: @lowmask_add_splat(
1139; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
1140; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1141; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[X]], <i8 32, i8 32>
1142; CHECK-NEXT:    ret <2 x i8> [[R]]
1143;
1144  %a = add <2 x i8> %x, <i8 -64, i8 -64> ; 0xc0
1145  store <2 x i8> %a, <2 x i8>* %p
1146  %r = and <2 x i8> %a, <i8 32, i8 32> ; 0x20
1147  ret <2 x i8> %r
1148}
1149
1150define <2 x i8> @lowmask_add_splat_undef(<2 x i8> %x, <2 x i8>* %p) {
1151; CHECK-LABEL: @lowmask_add_splat_undef(
1152; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 undef>
1153; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1154; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 undef, i8 32>
1155; CHECK-NEXT:    ret <2 x i8> [[R]]
1156;
1157  %a = add <2 x i8> %x, <i8 -64, i8 undef> ; 0xc0
1158  store <2 x i8> %a, <2 x i8>* %p
1159  %r = and <2 x i8> %a, <i8 undef, i8 32> ; 0x20
1160  ret <2 x i8> %r
1161}
1162
1163define <2 x i8> @lowmask_add_vec(<2 x i8> %x, <2 x i8>* %p) {
1164; CHECK-LABEL: @lowmask_add_vec(
1165; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -96, i8 -64>
1166; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1167; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 16, i8 32>
1168; CHECK-NEXT:    ret <2 x i8> [[R]]
1169;
1170  %a = add <2 x i8> %x, <i8 -96, i8 -64> ; 0xe0, 0xc0
1171  store <2 x i8> %a, <2 x i8>* %p
1172  %r = and <2 x i8> %a, <i8 16, i8 32> ; 0x10, 0x20
1173  ret <2 x i8> %r
1174}
1175
1176; Only one bit set
1177define i8 @flip_masked_bit(i8 %A) {
1178; CHECK-LABEL: @flip_masked_bit(
1179; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], 16
1180; CHECK-NEXT:    [[C:%.*]] = xor i8 [[TMP1]], 16
1181; CHECK-NEXT:    ret i8 [[C]]
1182;
1183  %B = add i8 %A, 16
1184  %C = and i8 %B, 16
1185  ret i8 %C
1186}
1187
1188define <2 x i8> @flip_masked_bit_uniform(<2 x i8> %A) {
1189; CHECK-LABEL: @flip_masked_bit_uniform(
1190; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[A:%.*]], <i8 16, i8 16>
1191; CHECK-NEXT:    [[C:%.*]] = xor <2 x i8> [[TMP1]], <i8 16, i8 16>
1192; CHECK-NEXT:    ret <2 x i8> [[C]]
1193;
1194  %B = add <2 x i8> %A, <i8 16, i8 16>
1195  %C = and <2 x i8> %B, <i8 16, i8 16>
1196  ret <2 x i8> %C
1197}
1198
1199define <2 x i8> @flip_masked_bit_undef(<2 x i8> %A) {
1200; CHECK-LABEL: @flip_masked_bit_undef(
1201; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A:%.*]], <i8 16, i8 undef>
1202; CHECK-NEXT:    [[C:%.*]] = and <2 x i8> [[B]], <i8 16, i8 undef>
1203; CHECK-NEXT:    ret <2 x i8> [[C]]
1204;
1205  %B = add <2 x i8> %A, <i8 16, i8 undef>
1206  %C = and <2 x i8> %B, <i8 16, i8 undef>
1207  ret <2 x i8> %C
1208}
1209
1210define <2 x i8> @flip_masked_bit_nonuniform(<2 x i8> %A) {
1211; CHECK-LABEL: @flip_masked_bit_nonuniform(
1212; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A:%.*]], <i8 16, i8 4>
1213; CHECK-NEXT:    [[C:%.*]] = and <2 x i8> [[B]], <i8 16, i8 4>
1214; CHECK-NEXT:    ret <2 x i8> [[C]]
1215;
1216  %B = add <2 x i8> %A, <i8 16, i8 4>
1217  %C = and <2 x i8> %B, <i8 16, i8 4>
1218  ret <2 x i8> %C
1219}
1220