[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / and.ll
blob53c7f09189ff560d716a95fc789b8910292a6417
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use8(i8)
5 declare void @use32(i32)
7 ; There should be no 'and' instructions left in any test.
9 define i32 @test1(i32 %A) {
10 ; CHECK-LABEL: @test1(
11 ; CHECK-NEXT:    ret i32 0
13   %B = and i32 %A, 0
14   ret i32 %B
17 define i32 @test2(i32 %A) {
18 ; CHECK-LABEL: @test2(
19 ; CHECK-NEXT:    ret i32 [[A:%.*]]
21   %B = and i32 %A, -1
22   ret i32 %B
25 define i1 @test3(i1 %A) {
26 ; CHECK-LABEL: @test3(
27 ; CHECK-NEXT:    ret i1 false
29   %B = and i1 %A, false
30   ret i1 %B
33 define i1 @test3_logical(i1 %A) {
34 ; CHECK-LABEL: @test3_logical(
35 ; CHECK-NEXT:    ret i1 false
37   %B = select i1 %A, i1 false, i1 false
38   ret i1 %B
41 define i1 @test4(i1 %A) {
42 ; CHECK-LABEL: @test4(
43 ; CHECK-NEXT:    ret i1 [[A:%.*]]
45   %B = and i1 %A, true
46   ret i1 %B
49 define i1 @test4_logical(i1 %A) {
50 ; CHECK-LABEL: @test4_logical(
51 ; CHECK-NEXT:    ret i1 [[A:%.*]]
53   %B = select i1 %A, i1 true, i1 false
54   ret i1 %B
57 define i32 @test5(i32 %A) {
58 ; CHECK-LABEL: @test5(
59 ; CHECK-NEXT:    ret i32 [[A:%.*]]
61   %B = and i32 %A, %A
62   ret i32 %B
65 define i1 @test6(i1 %A) {
66 ; CHECK-LABEL: @test6(
67 ; CHECK-NEXT:    ret i1 [[A:%.*]]
69   %B = and i1 %A, %A
70   ret i1 %B
73 define i1 @test6_logical(i1 %A) {
74 ; CHECK-LABEL: @test6_logical(
75 ; CHECK-NEXT:    ret i1 [[A:%.*]]
77   %B = select i1 %A, i1 %A, i1 false
78   ret i1 %B
81 ; A & ~A == 0
82 define i32 @test7(i32 %A) {
83 ; CHECK-LABEL: @test7(
84 ; CHECK-NEXT:    ret i32 0
86   %NotA = xor i32 %A, -1
87   %B = and i32 %A, %NotA
88   ret i32 %B
91 ; AND associates
92 define i8 @test8(i8 %A) {
93 ; CHECK-LABEL: @test8(
94 ; CHECK-NEXT:    ret i8 0
96   %B = and i8 %A, 3
97   %C = and i8 %B, 4
98   ret i8 %C
101 ; Test of sign bit, convert to setle %A, 0
102 define i1 @test9(i32 %A) {
103 ; CHECK-LABEL: @test9(
104 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
105 ; CHECK-NEXT:    ret i1 [[C]]
107   %B = and i32 %A, -2147483648
108   %C = icmp ne i32 %B, 0
109   ret i1 %C
112 ; Test of sign bit, convert to setle %A, 0
113 define i1 @test9a(i32 %A) {
114 ; CHECK-LABEL: @test9a(
115 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
116 ; CHECK-NEXT:    ret i1 [[C]]
118   %B = and i32 %A, -2147483648
119   %C = icmp ne i32 %B, 0
120   ret i1 %C
123 define i32 @test10(i32 %A) {
124 ; CHECK-LABEL: @test10(
125 ; CHECK-NEXT:    ret i32 1
127   %B = and i32 %A, 12
128   %C = xor i32 %B, 15
129   ; (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
130   %D = and i32 %C, 1
131   ret i32 %D
134 define i32 @test11(i32 %A, i32* %P) {
135 ; CHECK-LABEL: @test11(
136 ; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 3
137 ; CHECK-NEXT:    [[C:%.*]] = xor i32 [[B]], 12
138 ; CHECK-NEXT:    store i32 [[C]], i32* [[P:%.*]], align 4
139 ; CHECK-NEXT:    ret i32 3
141   %B = or i32 %A, 3
142   %C = xor i32 %B, 12
143   ; additional use of C
144   store i32 %C, i32* %P
145   ; %C = and uint %B, 3 --> 3
146   %D = and i32 %C, 3
147   ret i32 %D
150 define i1 @test12(i32 %A, i32 %B) {
151 ; CHECK-LABEL: @test12(
152 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
153 ; CHECK-NEXT:    ret i1 [[C1]]
155   %C1 = icmp ult i32 %A, %B
156   %C2 = icmp ule i32 %A, %B
157   ; (A < B) & (A <= B) === (A < B)
158   %D = and i1 %C1, %C2
159   ret i1 %D
162 define i1 @test12_logical(i32 %A, i32 %B) {
163 ; CHECK-LABEL: @test12_logical(
164 ; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
165 ; CHECK-NEXT:    ret i1 [[C1]]
167   %C1 = icmp ult i32 %A, %B
168   %C2 = icmp ule i32 %A, %B
169   ; (A < B) & (A <= B) === (A < B)
170   %D = select i1 %C1, i1 %C2, i1 false
171   ret i1 %D
174 define i1 @test13(i32 %A, i32 %B) {
175 ; CHECK-LABEL: @test13(
176 ; CHECK-NEXT:    ret i1 false
178   %C1 = icmp ult i32 %A, %B
179   %C2 = icmp ugt i32 %A, %B
180   ; (A < B) & (A > B) === false
181   %D = and i1 %C1, %C2
182   ret i1 %D
185 define i1 @test13_logical(i32 %A, i32 %B) {
186 ; CHECK-LABEL: @test13_logical(
187 ; CHECK-NEXT:    ret i1 false
189   %C1 = icmp ult i32 %A, %B
190   %C2 = icmp ugt i32 %A, %B
191   ; (A < B) & (A > B) === false
192   %D = select i1 %C1, i1 %C2, i1 false
193   ret i1 %D
196 define i1 @test14(i8 %A) {
197 ; CHECK-LABEL: @test14(
198 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], 0
199 ; CHECK-NEXT:    ret i1 [[C]]
201   %B = and i8 %A, -128
202   %C = icmp ne i8 %B, 0
203   ret i1 %C
206 define i8 @test15(i8 %A) {
207 ; CHECK-LABEL: @test15(
208 ; CHECK-NEXT:    ret i8 0
210   %B = lshr i8 %A, 7
211   ; Always equals zero
212   %C = and i8 %B, 2
213   ret i8 %C
216 define i8 @test16(i8 %A) {
217 ; CHECK-LABEL: @test16(
218 ; CHECK-NEXT:    ret i8 0
220   %B = shl i8 %A, 2
221   %C = and i8 %B, 3
222   ret i8 %C
225 define i1 @test18(i32 %A) {
226 ; CHECK-LABEL: @test18(
227 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A:%.*]], 127
228 ; CHECK-NEXT:    ret i1 [[C]]
230   %B = and i32 %A, -128
231   ;; C >= 128
232   %C = icmp ne i32 %B, 0
233   ret i1 %C
236 define <2 x i1> @test18_vec(<2 x i32> %A) {
237 ; CHECK-LABEL: @test18_vec(
238 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 127, i32 127>
239 ; CHECK-NEXT:    ret <2 x i1> [[C]]
241   %B = and <2 x i32> %A, <i32 -128, i32 -128>
242   %C = icmp ne <2 x i32> %B, zeroinitializer
243   ret <2 x i1> %C
246 define i1 @test18a(i8 %A) {
247 ; CHECK-LABEL: @test18a(
248 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A:%.*]], 2
249 ; CHECK-NEXT:    ret i1 [[C]]
251   %B = and i8 %A, -2
252   %C = icmp eq i8 %B, 0
253   ret i1 %C
256 define <2 x i1> @test18a_vec(<2 x i8> %A) {
257 ; CHECK-LABEL: @test18a_vec(
258 ; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], <i8 2, i8 2>
259 ; CHECK-NEXT:    ret <2 x i1> [[C]]
261   %B = and <2 x i8> %A, <i8 -2, i8 -2>
262   %C = icmp eq <2 x i8> %B, zeroinitializer
263   ret <2 x i1> %C
266 define i32 @test19(i32 %A) {
267 ; CHECK-LABEL: @test19(
268 ; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 3
269 ; CHECK-NEXT:    ret i32 [[B]]
271   %B = shl i32 %A, 3
272   ;; Clearing a zero bit
273   %C = and i32 %B, -2
274   ret i32 %C
277 define i8 @test20(i8 %A) {
278 ; CHECK-LABEL: @test20(
279 ; CHECK-NEXT:    [[C:%.*]] = lshr i8 [[A:%.*]], 7
280 ; CHECK-NEXT:    ret i8 [[C]]
282   %C = lshr i8 %A, 7
283   ;; Unneeded
284   %D = and i8 %C, 1
285   ret i8 %D
288 define i1 @test23(i32 %A) {
289 ; CHECK-LABEL: @test23(
290 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], 2
291 ; CHECK-NEXT:    ret i1 [[TMP1]]
293   %B = icmp sgt i32 %A, 1
294   %C = icmp sle i32 %A, 2
295   %D = and i1 %B, %C
296   ret i1 %D
299 define i1 @test23_logical(i32 %A) {
300 ; CHECK-LABEL: @test23_logical(
301 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], 2
302 ; CHECK-NEXT:    ret i1 [[TMP1]]
304   %B = icmp sgt i32 %A, 1
305   %C = icmp sle i32 %A, 2
306   %D = select i1 %B, i1 %C, i1 false
307   ret i1 %D
310 define <2 x i1> @test23vec(<2 x i32> %A) {
311 ; CHECK-LABEL: @test23vec(
312 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 2, i32 2>
313 ; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
315   %B = icmp sgt <2 x i32> %A, <i32 1, i32 1>
316   %C = icmp sle <2 x i32> %A, <i32 2, i32 2>
317   %D = and <2 x i1> %B, %C
318   ret <2 x i1> %D
321 define i1 @test24(i32 %A) {
322 ; CHECK-LABEL: @test24(
323 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 2
324 ; CHECK-NEXT:    ret i1 [[TMP1]]
326   %B = icmp sgt i32 %A, 1
327   %C = icmp ne i32 %A, 2
328   ;; A > 2
329   %D = and i1 %B, %C
330   ret i1 %D
333 define i1 @test24_logical(i32 %A) {
334 ; CHECK-LABEL: @test24_logical(
335 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 2
336 ; CHECK-NEXT:    ret i1 [[TMP1]]
338   %B = icmp sgt i32 %A, 1
339   %C = icmp ne i32 %A, 2
340   ;; A > 2
341   %D = select i1 %B, i1 %C, i1 false
342   ret i1 %D
345 define i1 @test25(i32 %A) {
346 ; CHECK-LABEL: @test25(
347 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -50
348 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 50
349 ; CHECK-NEXT:    ret i1 [[TMP2]]
351   %B = icmp sge i32 %A, 50
352   %C = icmp slt i32 %A, 100
353   %D = and i1 %B, %C
354   ret i1 %D
357 define i1 @test25_logical(i32 %A) {
358 ; CHECK-LABEL: @test25_logical(
359 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -50
360 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 50
361 ; CHECK-NEXT:    ret i1 [[TMP2]]
363   %B = icmp sge i32 %A, 50
364   %C = icmp slt i32 %A, 100
365   %D = select i1 %B, i1 %C, i1 false
366   ret i1 %D
369 define <2 x i1> @test25vec(<2 x i32> %A) {
370 ; CHECK-LABEL: @test25vec(
371 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -50, i32 -50>
372 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 50, i32 50>
373 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
375   %B = icmp sge <2 x i32> %A, <i32 50, i32 50>
376   %C = icmp slt <2 x i32> %A, <i32 100, i32 100>
377   %D = and <2 x i1> %B, %C
378   ret <2 x i1> %D
381 define i8 @test27(i8 %A) {
382 ; CHECK-LABEL: @test27(
383 ; CHECK-NEXT:    ret i8 0
385   %B = and i8 %A, 4
386   %C = sub i8 %B, 16
387   ;; 0xF0
388   %D = and i8 %C, -16
389   %E = add i8 %D, 16
390   ret i8 %E
393 ;; This is just a zero-extending shr.
394 define i32 @test28(i32 %X) {
395 ; CHECK-LABEL: @test28(
396 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 24
397 ; CHECK-NEXT:    ret i32 [[TMP1]]
399   ;; Sign extend
400   %Y = ashr i32 %X, 24
401   ;; Mask out sign bits
402   %Z = and i32 %Y, 255
403   ret i32 %Z
406 define i32 @test29(i8 %X) {
407 ; CHECK-LABEL: @test29(
408 ; CHECK-NEXT:    [[Y:%.*]] = zext i8 [[X:%.*]] to i32
409 ; CHECK-NEXT:    ret i32 [[Y]]
411   %Y = zext i8 %X to i32
412   ;; Zero extend makes this unneeded.
413   %Z = and i32 %Y, 255
414   ret i32 %Z
417 define i32 @test30(i1 %X) {
418 ; CHECK-LABEL: @test30(
419 ; CHECK-NEXT:    [[Y:%.*]] = zext i1 [[X:%.*]] to i32
420 ; CHECK-NEXT:    ret i32 [[Y]]
422   %Y = zext i1 %X to i32
423   %Z = and i32 %Y, 1
424   ret i32 %Z
427 define i32 @test31(i1 %X) {
428 ; CHECK-LABEL: @test31(
429 ; CHECK-NEXT:    [[Z:%.*]] = select i1 [[X:%.*]], i32 16, i32 0
430 ; CHECK-NEXT:    ret i32 [[Z]]
432   %Y = zext i1 %X to i32
433   %Z = shl i32 %Y, 4
434   %A = and i32 %Z, 16
435   ret i32 %A
438 ; Demanded bit analysis allows us to eliminate the add.
440 define <2 x i32> @and_demanded_bits_splat_vec(<2 x i32> %x) {
441 ; CHECK-LABEL: @and_demanded_bits_splat_vec(
442 ; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> [[X:%.*]], <i32 7, i32 7>
443 ; CHECK-NEXT:    ret <2 x i32> [[Z]]
445   %y = add <2 x i32> %x, <i32 8, i32 8>
446   %z = and <2 x i32> %y, <i32 7, i32 7>
447   ret <2 x i32> %z
450 ; zext (x >> 8) has all zeros in the high 24-bits:  0x000000xx
451 ; (y | 255) has all ones in the low 8-bits: 0xyyyyyyff
452 ; 'and' of those is all known bits - it's just 'z'.
454 define i32 @and_zext_demanded(i16 %x, i32 %y) {
455 ; CHECK-LABEL: @and_zext_demanded(
456 ; CHECK-NEXT:    [[S:%.*]] = lshr i16 [[X:%.*]], 8
457 ; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[S]] to i32
458 ; CHECK-NEXT:    ret i32 [[Z]]
460   %s = lshr i16 %x, 8
461   %z = zext i16 %s to i32
462   %o = or i32 %y, 255
463   %a = and i32 %o, %z
464   ret i32 %a
467 define i32 @test32(i32 %In) {
468 ; CHECK-LABEL: @test32(
469 ; CHECK-NEXT:    ret i32 0
471   %Y = and i32 %In, 16
472   %Z = lshr i32 %Y, 2
473   %A = and i32 %Z, 1
474   ret i32 %A
477 ;; Code corresponding to one-bit bitfield ^1.
478 define i32 @test33(i32 %b) {
479 ; CHECK-LABEL: @test33(
480 ; CHECK-NEXT:    [[T13:%.*]] = xor i32 [[B:%.*]], 1
481 ; CHECK-NEXT:    ret i32 [[T13]]
483   %t4.mask = and i32 %b, 1
484   %t10 = xor i32 %t4.mask, 1
485   %t12 = and i32 %b, -2
486   %t13 = or i32 %t12, %t10
487   ret i32 %t13
490 define i32 @test33b(i32 %b) {
491 ; CHECK-LABEL: @test33b(
492 ; CHECK-NEXT:    [[T13:%.*]] = xor i32 [[B:%.*]], 1
493 ; CHECK-NEXT:    ret i32 [[T13]]
495   %t4.mask = and i32 %b, 1
496   %t10 = xor i32 %t4.mask, 1
497   %t12 = and i32 %b, -2
498   %t13 = or i32 %t10, %t12
499   ret i32 %t13
502 define <2 x i32> @test33vec(<2 x i32> %b) {
503 ; CHECK-LABEL: @test33vec(
504 ; CHECK-NEXT:    [[T13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
505 ; CHECK-NEXT:    ret <2 x i32> [[T13]]
507   %t4.mask = and <2 x i32> %b, <i32 1, i32 1>
508   %t10 = xor <2 x i32> %t4.mask, <i32 1, i32 1>
509   %t12 = and <2 x i32> %b, <i32 -2, i32 -2>
510   %t13 = or <2 x i32> %t12, %t10
511   ret <2 x i32> %t13
514 define <2 x i32> @test33vecb(<2 x i32> %b) {
515 ; CHECK-LABEL: @test33vecb(
516 ; CHECK-NEXT:    [[T13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
517 ; CHECK-NEXT:    ret <2 x i32> [[T13]]
519   %t4.mask = and <2 x i32> %b, <i32 1, i32 1>
520   %t10 = xor <2 x i32> %t4.mask, <i32 1, i32 1>
521   %t12 = and <2 x i32> %b, <i32 -2, i32 -2>
522   %t13 = or <2 x i32> %t10, %t12
523   ret <2 x i32> %t13
526 define i32 @test34(i32 %A, i32 %B) {
527 ; CHECK-LABEL: @test34(
528 ; CHECK-NEXT:    ret i32 [[B:%.*]]
530   %t2 = or i32 %B, %A
531   %t4 = and i32 %t2, %B
532   ret i32 %t4
535 ; FIXME: This test should only need -instsimplify (ValueTracking / computeKnownBits), not -instcombine.
537 define <2 x i32> @PR24942(<2 x i32> %x) {
538 ; CHECK-LABEL: @PR24942(
539 ; CHECK-NEXT:    ret <2 x i32> zeroinitializer
541   %lshr = lshr <2 x i32> %x, <i32 31, i32 31>
542   %and = and <2 x i32> %lshr, <i32 2, i32 2>
543   ret <2 x i32> %and
546 define i64 @test35(i32 %X) {
547 ; CHECK-LABEL: @test35(
548 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
549 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
550 ; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
551 ; CHECK-NEXT:    ret i64 [[RES]]
553   %zext = zext i32 %X to i64
554   %zsub = sub i64 0, %zext
555   %res = and i64 %zsub, 240
556   ret i64 %res
559 define <2 x i64> @test35_uniform(<2 x i32> %X) {
560 ; CHECK-LABEL: @test35_uniform(
561 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]]
562 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 240, i32 240>
563 ; CHECK-NEXT:    [[RES:%.*]] = zext <2 x i32> [[TMP2]] to <2 x i64>
564 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
566   %zext = zext <2 x i32> %X to <2 x i64>
567   %zsub = sub <2 x i64> zeroinitializer, %zext
568   %res = and <2 x i64> %zsub, <i64 240, i64 240>
569   ret <2 x i64> %res
572 define i64 @test36(i32 %X) {
573 ; CHECK-LABEL: @test36(
574 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
575 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
576 ; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
577 ; CHECK-NEXT:    ret i64 [[RES]]
579   %zext = zext i32 %X to i64
580   %zsub = add i64 %zext, 7
581   %res = and i64 %zsub, 240
582   ret i64 %res
585 define <2 x i64> @test36_uniform(<2 x i32> %X) {
586 ; CHECK-LABEL: @test36_uniform(
587 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
588 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 240, i32 240>
589 ; CHECK-NEXT:    [[RES:%.*]] = zext <2 x i32> [[TMP2]] to <2 x i64>
590 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
592   %zext = zext <2 x i32> %X to <2 x i64>
593   %zsub = add <2 x i64> %zext, <i64 7, i64 7>
594   %res = and <2 x i64> %zsub, <i64 240, i64 240>
595   ret <2 x i64> %res
598 define <2 x i64> @test36_undef(<2 x i32> %X) {
599 ; CHECK-LABEL: @test36_undef(
600 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>
601 ; CHECK-NEXT:    [[ZSUB:%.*]] = add <2 x i64> [[ZEXT]], <i64 7, i64 undef>
602 ; CHECK-NEXT:    [[RES:%.*]] = and <2 x i64> [[ZSUB]], <i64 240, i64 undef>
603 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
605   %zext = zext <2 x i32> %X to <2 x i64>
606   %zsub = add <2 x i64> %zext, <i64 7, i64 undef>
607   %res = and <2 x i64> %zsub, <i64 240, i64 undef>
608   ret <2 x i64> %res
611 define i64 @test37(i32 %X) {
612 ; CHECK-LABEL: @test37(
613 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], 7
614 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 240
615 ; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP2]] to i64
616 ; CHECK-NEXT:    ret i64 [[RES]]
618   %zext = zext i32 %X to i64
619   %zsub = mul i64 %zext, 7
620   %res = and i64 %zsub, 240
621   ret i64 %res
624 define <2 x i64> @test37_uniform(<2 x i32> %X) {
625 ; CHECK-LABEL: @test37_uniform(
626 ; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], <i32 7, i32 7>
627 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 240, i32 240>
628 ; CHECK-NEXT:    [[RES:%.*]] = zext <2 x i32> [[TMP2]] to <2 x i64>
629 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
631   %zext = zext <2 x i32> %X to <2 x i64>
632   %zsub = mul <2 x i64> %zext, <i64 7, i64 7>
633   %res = and <2 x i64> %zsub, <i64 240, i64 240>
634   ret <2 x i64> %res
637 define <2 x i64> @test37_nonuniform(<2 x i32> %X) {
638 ; CHECK-LABEL: @test37_nonuniform(
639 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64>
640 ; CHECK-NEXT:    [[ZSUB:%.*]] = mul nuw nsw <2 x i64> [[ZEXT]], <i64 7, i64 9>
641 ; CHECK-NEXT:    [[RES:%.*]] = and <2 x i64> [[ZSUB]], <i64 240, i64 110>
642 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
644   %zext = zext <2 x i32> %X to <2 x i64>
645   %zsub = mul <2 x i64> %zext, <i64 7, i64 9>
646   %res = and <2 x i64> %zsub, <i64 240, i64 110>
647   ret <2 x i64> %res
650 define i64 @test38(i32 %X) {
651 ; CHECK-LABEL: @test38(
652 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
653 ; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP1]] to i64
654 ; CHECK-NEXT:    ret i64 [[RES]]
656   %zext = zext i32 %X to i64
657   %zsub = xor i64 %zext, 7
658   %res = and i64 %zsub, 240
659   ret i64 %res
662 define i64 @test39(i32 %X) {
663 ; CHECK-LABEL: @test39(
664 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
665 ; CHECK-NEXT:    [[RES:%.*]] = zext i32 [[TMP1]] to i64
666 ; CHECK-NEXT:    ret i64 [[RES]]
668   %zext = zext i32 %X to i64
669   %zsub = or i64 %zext, 7
670   %res = and i64 %zsub, 240
671   ret i64 %res
674 define i32 @test40(i1 %C) {
675 ; CHECK-LABEL: @test40(
676 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], i32 104, i32 10
677 ; CHECK-NEXT:    ret i32 [[A]]
679   %A = select i1 %C, i32 1000, i32 10
680   %V = and i32 %A, 123
681   ret i32 %V
684 define <2 x i32> @test40vec(i1 %C) {
685 ; CHECK-LABEL: @test40vec(
686 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 104>, <2 x i32> <i32 10, i32 10>
687 ; CHECK-NEXT:    ret <2 x i32> [[A]]
689   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
690   %V = and <2 x i32> %A, <i32 123, i32 123>
691   ret <2 x i32> %V
694 define <2 x i32> @test40vec2(i1 %C) {
695 ; CHECK-LABEL: @test40vec2(
696 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 324>, <2 x i32> <i32 10, i32 12>
697 ; CHECK-NEXT:    ret <2 x i32> [[V]]
699   %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
700   %V = and <2 x i32> %A, <i32 123, i32 333>
701   ret <2 x i32> %V
704 define i32 @test41(i1 %which) {
705 ; CHECK-LABEL: @test41(
706 ; CHECK-NEXT:  entry:
707 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
708 ; CHECK:       delay:
709 ; CHECK-NEXT:    br label [[FINAL]]
710 ; CHECK:       final:
711 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 104, [[ENTRY:%.*]] ], [ 10, [[DELAY]] ]
712 ; CHECK-NEXT:    ret i32 [[A]]
714 entry:
715   br i1 %which, label %final, label %delay
717 delay:
718   br label %final
720 final:
721   %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
722   %value = and i32 %A, 123
723   ret i32 %value
726 define <2 x i32> @test41vec(i1 %which) {
727 ; CHECK-LABEL: @test41vec(
728 ; CHECK-NEXT:  entry:
729 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
730 ; CHECK:       delay:
731 ; CHECK-NEXT:    br label [[FINAL]]
732 ; CHECK:       final:
733 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 104>, [[ENTRY:%.*]] ], [ <i32 10, i32 10>, [[DELAY]] ]
734 ; CHECK-NEXT:    ret <2 x i32> [[A]]
736 entry:
737   br i1 %which, label %final, label %delay
739 delay:
740   br label %final
742 final:
743   %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
744   %value = and <2 x i32> %A, <i32 123, i32 123>
745   ret <2 x i32> %value
748 define <2 x i32> @test41vec2(i1 %which) {
749 ; CHECK-LABEL: @test41vec2(
750 ; CHECK-NEXT:  entry:
751 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
752 ; CHECK:       delay:
753 ; CHECK-NEXT:    br label [[FINAL]]
754 ; CHECK:       final:
755 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 324>, [[ENTRY:%.*]] ], [ <i32 10, i32 12>, [[DELAY]] ]
756 ; CHECK-NEXT:    ret <2 x i32> [[A]]
758 entry:
759   br i1 %which, label %final, label %delay
761 delay:
762   br label %final
764 final:
765   %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
766   %value = and <2 x i32> %A, <i32 123, i32 333>
767   ret <2 x i32> %value
770 define i32 @test42(i32 %a, i32 %c, i32 %d) {
771 ; CHECK-LABEL: @test42(
772 ; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
773 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
774 ; CHECK-NEXT:    ret i32 [[AND]]
776   %force = mul i32 %c, %d ; forces the complexity sorting
777   %or = or i32 %a, %force
778   %nota = xor i32 %a, -1
779   %xor = xor i32 %nota, %force
780   %and = and i32 %xor, %or
781   ret i32 %and
784 define i32 @test43(i32 %a, i32 %c, i32 %d) {
785 ; CHECK-LABEL: @test43(
786 ; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
787 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
788 ; CHECK-NEXT:    ret i32 [[AND]]
790   %force = mul i32 %c, %d ; forces the complexity sorting
791   %or = or i32 %a, %force
792   %nota = xor i32 %a, -1
793   %xor = xor i32 %nota, %force
794   %and = and i32 %or, %xor
795   ret i32 %and
798 ; (~y | x) & y -> x & y
799 define i32 @test44(i32 %x, i32 %y) nounwind {
800 ; CHECK-LABEL: @test44(
801 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
802 ; CHECK-NEXT:    ret i32 [[A]]
804   %n = xor i32 %y, -1
805   %o = or i32 %n, %x
806   %a = and i32 %o, %y
807   ret i32 %a
810 ; (x | ~y) & y -> x & y
811 define i32 @test45(i32 %x, i32 %y) nounwind {
812 ; CHECK-LABEL: @test45(
813 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
814 ; CHECK-NEXT:    ret i32 [[A]]
816   %n = xor i32 %y, -1
817   %o = or i32 %x, %n
818   %a = and i32 %o, %y
819   ret i32 %a
822 ; y & (~y | x) -> y | x
823 define i32 @test46(i32 %x, i32 %y) nounwind {
824 ; CHECK-LABEL: @test46(
825 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
826 ; CHECK-NEXT:    ret i32 [[A]]
828   %n = xor i32 %y, -1
829   %o = or i32 %n, %x
830   %a = and i32 %y, %o
831   ret i32 %a
834 ; y & (x | ~y) -> y | x
835 define i32 @test47(i32 %x, i32 %y) nounwind {
836 ; CHECK-LABEL: @test47(
837 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
838 ; CHECK-NEXT:    ret i32 [[A]]
840   %n = xor i32 %y, -1
841   %o = or i32 %x, %n
842   %a = and i32 %y, %o
843   ret i32 %a
846 ; In the next 4 tests, vary the types and predicates for extra coverage.
847 ; (X & (Y | ~X)) -> (X & Y), where 'not' is an inverted cmp
849 define i1 @and_orn_cmp_1(i32 %a, i32 %b, i32 %c) {
850 ; CHECK-LABEL: @and_orn_cmp_1(
851 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
852 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
853 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
854 ; CHECK-NEXT:    ret i1 [[AND]]
856   %x = icmp sgt i32 %a, %b
857   %x_inv = icmp sle i32 %a, %b
858   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
859   %or = or i1 %y, %x_inv
860   %and = and i1 %x, %or
861   ret i1 %and
864 define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
865 ; CHECK-LABEL: @and_orn_cmp_1_logical(
866 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
867 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
868 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X]], i1 [[Y]], i1 false
869 ; CHECK-NEXT:    ret i1 [[AND]]
871   %x = icmp sgt i32 %a, %b
872   %x_inv = icmp sle i32 %a, %b
873   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
874   %or = select i1 %y, i1 true, i1 %x_inv
875   %and = select i1 %x, i1 %or, i1 false
876   ret i1 %and
879 ; Commute the 'and':
880 ; ((Y | ~X) & X) -> (X & Y), where 'not' is an inverted cmp
882 define <2 x i1> @and_orn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
883 ; CHECK-LABEL: @and_orn_cmp_2(
884 ; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
885 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
886 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[Y]], [[X]]
887 ; CHECK-NEXT:    ret <2 x i1> [[AND]]
889   %x = icmp sge <2 x i32> %a, %b
890   %x_inv = icmp slt <2 x i32> %a, %b
891   %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
892   %or = or <2 x i1> %y, %x_inv
893   %and = and <2 x i1> %or, %x
894   ret <2 x i1> %and
897 ; Commute the 'or':
898 ; (X & (~X | Y)) -> (X & Y), where 'not' is an inverted cmp
900 define i1 @and_orn_cmp_3(i72 %a, i72 %b, i72 %c) {
901 ; CHECK-LABEL: @and_orn_cmp_3(
902 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
903 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
904 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
905 ; CHECK-NEXT:    ret i1 [[AND]]
907   %x = icmp ugt i72 %a, %b
908   %x_inv = icmp ule i72 %a, %b
909   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
910   %or = or i1 %x_inv, %y
911   %and = and i1 %x, %or
912   ret i1 %and
915 define i1 @and_orn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
916 ; CHECK-LABEL: @and_orn_cmp_3_logical(
917 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
918 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
919 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X]], i1 [[Y]], i1 false
920 ; CHECK-NEXT:    ret i1 [[AND]]
922   %x = icmp ugt i72 %a, %b
923   %x_inv = icmp ule i72 %a, %b
924   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
925   %or = select i1 %x_inv, i1 true, i1 %y
926   %and = select i1 %x, i1 %or, i1 false
927   ret i1 %and
930 ; Commute the 'and':
931 ; ((~X | Y) & X) -> (X & Y), where 'not' is an inverted cmp
933 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
934 ; CHECK-LABEL: @or_andn_cmp_4(
935 ; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
936 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
937 ; CHECK-NEXT:    [[AND:%.*]] = and <3 x i1> [[Y]], [[X]]
938 ; CHECK-NEXT:    ret <3 x i1> [[AND]]
940   %x = icmp eq <3 x i32> %a, %b
941   %x_inv = icmp ne <3 x i32> %a, %b
942   %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
943   %or = or <3 x i1> %x_inv, %y
944   %and = and <3 x i1> %or, %x
945   ret <3 x i1> %and
948 ; In the next 4 tests, vary the types and predicates for extra coverage.
949 ; (~X & (Y | X)) -> (~X & Y), where 'not' is an inverted cmp
951 define i1 @andn_or_cmp_1(i37 %a, i37 %b, i37 %c) {
952 ; CHECK-LABEL: @andn_or_cmp_1(
953 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
954 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
955 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_INV]], [[Y]]
956 ; CHECK-NEXT:    ret i1 [[AND]]
958   %x = icmp sgt i37 %a, %b
959   %x_inv = icmp sle i37 %a, %b
960   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
961   %or = or i1 %y, %x
962   %and = and i1 %x_inv, %or
963   ret i1 %and
966 define i1 @andn_or_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
967 ; CHECK-LABEL: @andn_or_cmp_1_logical(
968 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
969 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
970 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X_INV]], i1 [[Y]], i1 false
971 ; CHECK-NEXT:    ret i1 [[AND]]
973   %x = icmp sgt i37 %a, %b
974   %x_inv = icmp sle i37 %a, %b
975   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
976   %or = select i1 %y, i1 true, i1 %x
977   %and = select i1 %x_inv, i1 %or, i1 false
978   ret i1 %and
981 ; Commute the 'and':
982 ; ((Y | X) & ~X) -> (~X & Y), where 'not' is an inverted cmp
984 define i1 @andn_or_cmp_2(i16 %a, i16 %b, i16 %c) {
985 ; CHECK-LABEL: @andn_or_cmp_2(
986 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
987 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
988 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
989 ; CHECK-NEXT:    ret i1 [[AND]]
991   %x = icmp sge i16 %a, %b
992   %x_inv = icmp slt i16 %a, %b
993   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
994   %or = or i1 %y, %x
995   %and = and i1 %or, %x_inv
996   ret i1 %and
999 define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1000 ; CHECK-LABEL: @andn_or_cmp_2_logical(
1001 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1002 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1003 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[Y]], i1 [[X_INV]], i1 false
1004 ; CHECK-NEXT:    ret i1 [[AND]]
1006   %x = icmp sge i16 %a, %b
1007   %x_inv = icmp slt i16 %a, %b
1008   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1009   %or = select i1 %y, i1 true, i1 %x
1010   %and = select i1 %or, i1 %x_inv, i1 false
1011   ret i1 %and
1014 ; Commute the 'or':
1015 ; (~X & (X | Y)) -> (~X & Y), where 'not' is an inverted cmp
1017 define <4 x i1> @andn_or_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1018 ; CHECK-LABEL: @andn_or_cmp_3(
1019 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1020 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1021 ; CHECK-NEXT:    [[AND:%.*]] = and <4 x i1> [[X_INV]], [[Y]]
1022 ; CHECK-NEXT:    ret <4 x i1> [[AND]]
1024   %x = icmp ugt <4 x i32> %a, %b
1025   %x_inv = icmp ule <4 x i32> %a, %b
1026   %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
1027   %or = or <4 x i1> %x, %y
1028   %and = and <4 x i1> %x_inv, %or
1029   ret <4 x i1> %and
1032 ; Commute the 'and':
1033 ; ((X | Y) & ~X) -> (~X & Y), where 'not' is an inverted cmp
1035 define i1 @andn_or_cmp_4(i32 %a, i32 %b, i32 %c) {
1036 ; CHECK-LABEL: @andn_or_cmp_4(
1037 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1038 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1039 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
1040 ; CHECK-NEXT:    ret i1 [[AND]]
1042   %x = icmp eq i32 %a, %b
1043   %x_inv = icmp ne i32 %a, %b
1044   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1045   %or = or i1 %x, %y
1046   %and = and i1 %or, %x_inv
1047   ret i1 %and
1050 define i1 @andn_or_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1051 ; CHECK-LABEL: @andn_or_cmp_4_logical(
1052 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1053 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1054 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X_INV]], i1 [[Y]], i1 false
1055 ; CHECK-NEXT:    ret i1 [[AND]]
1057   %x = icmp eq i32 %a, %b
1058   %x_inv = icmp ne i32 %a, %b
1059   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1060   %or = select i1 %x, i1 true, i1 %y
1061   %and = select i1 %or, i1 %x_inv, i1 false
1062   ret i1 %and
1065 define i32 @lowbitmask_casted_shift(i8 %x) {
1066 ; CHECK-LABEL: @lowbitmask_casted_shift(
1067 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
1068 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[TMP1]], 1
1069 ; CHECK-NEXT:    ret i32 [[R]]
1071   %a = ashr i8 %x, 1
1072   %s = sext i8 %a to i32
1073   %r = and i32 %s, 2147483647
1074   ret i32 %r
1077 ; Negative test - mask constant is too big.
1079 define i32 @lowbitmask_casted_shift_wrong_mask1(i8 %x) {
1080 ; CHECK-LABEL: @lowbitmask_casted_shift_wrong_mask1(
1081 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 2
1082 ; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
1083 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 2147483647
1084 ; CHECK-NEXT:    ret i32 [[R]]
1086   %a = ashr i8 %x, 2
1087   %s = sext i8 %a to i32
1088   %r = and i32 %s, 2147483647 ; 0x7fffffff
1089   ret i32 %r
1092 ; Negative test - mask constant is too small.
1094 define i32 @lowbitmask_casted_shift_wrong_mask2(i8 %x) {
1095 ; CHECK-LABEL: @lowbitmask_casted_shift_wrong_mask2(
1096 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 2
1097 ; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
1098 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 536870911
1099 ; CHECK-NEXT:    ret i32 [[R]]
1101   %a = ashr i8 %x, 2
1102   %s = sext i8 %a to i32
1103   %r = and i32 %s, 536870911  ; 0x1fffffff
1104   ret i32 %r
1107 ; Extra use of shift is ok.
1109 define i32 @lowbitmask_casted_shift_use1(i8 %x) {
1110 ; CHECK-LABEL: @lowbitmask_casted_shift_use1(
1111 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 3
1112 ; CHECK-NEXT:    call void @use8(i8 [[A]])
1113 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
1114 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[TMP1]], 3
1115 ; CHECK-NEXT:    ret i32 [[R]]
1117   %a = ashr i8 %x, 3
1118   call void @use8(i8 %a)
1119   %s = sext i8 %a to i32
1120   %r = and i32 %s, 536870911
1121   ret i32 %r
1124 ; Negative test - extra use of sext requires more instructions.
1126 define i32 @lowbitmask_casted_shift_use2(i8 %x) {
1127 ; CHECK-LABEL: @lowbitmask_casted_shift_use2(
1128 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 3
1129 ; CHECK-NEXT:    [[S:%.*]] = sext i8 [[A]] to i32
1130 ; CHECK-NEXT:    call void @use32(i32 [[S]])
1131 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[S]], 536870911
1132 ; CHECK-NEXT:    ret i32 [[R]]
1134   %a = ashr i8 %x, 3
1135   %s = sext i8 %a to i32
1136   call void @use32(i32 %s)
1137   %r = and i32 %s, 536870911
1138   ret i32 %r
1141 ; Vectors/weird types are ok.
1143 define <2 x i59> @lowbitmask_casted_shift_vec_splat(<2 x i47> %x) {
1144 ; CHECK-LABEL: @lowbitmask_casted_shift_vec_splat(
1145 ; CHECK-NEXT:    [[TMP1:%.*]] = sext <2 x i47> [[X:%.*]] to <2 x i59>
1146 ; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i59> [[TMP1]], <i59 5, i59 5>
1147 ; CHECK-NEXT:    ret <2 x i59> [[R]]
1149   %a = ashr <2 x i47> %x, <i47 5, i47 5>
1150   %s = sext <2 x i47> %a to <2 x i59>
1151   %r = and <2 x i59> %s, <i59 18014398509481983, i59 18014398509481983>  ;  -1 u>> 5 == 0x3f_ffff_ffff_ffff
1152   ret <2 x i59> %r
1155 define i32 @lowmask_sext_in_reg(i32 %x) {
1156 ; CHECK-LABEL: @lowmask_sext_in_reg(
1157 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
1158 ; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 20
1159 ; CHECK-NEXT:    call void @use32(i32 [[R]])
1160 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], 4095
1161 ; CHECK-NEXT:    ret i32 [[AND]]
1163   %l = shl i32 %x, 20
1164   %r = ashr i32 %l, 20
1165   call void @use32(i32 %r)
1166   %and = and i32 %r, 4095
1167   ret i32 %and
1170 ; Negative test - mismatched shift amounts
1172 define i32 @lowmask_not_sext_in_reg(i32 %x) {
1173 ; CHECK-LABEL: @lowmask_not_sext_in_reg(
1174 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 19
1175 ; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[L]], 20
1176 ; CHECK-NEXT:    call void @use32(i32 [[R]])
1177 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
1178 ; CHECK-NEXT:    ret i32 [[AND]]
1180   %l = shl i32 %x, 19
1181   %r = ashr i32 %l, 20
1182   call void @use32(i32 %r)
1183   %and = and i32 %r, 4095
1184   ret i32 %and
1187 ; Negative test - too much shift for mask
1189 define i32 @not_lowmask_sext_in_reg(i32 %x) {
1190 ; CHECK-LABEL: @not_lowmask_sext_in_reg(
1191 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 20
1192 ; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 20
1193 ; CHECK-NEXT:    call void @use32(i32 [[R]])
1194 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4096
1195 ; CHECK-NEXT:    ret i32 [[AND]]
1197   %l = shl i32 %x, 20
1198   %r = ashr i32 %l, 20
1199   call void @use32(i32 %r)
1200   %and = and i32 %r, 4096
1201   ret i32 %and
1204 ; Negative test - too much shift for mask
1206 define i32 @not_lowmask_sext_in_reg2(i32 %x) {
1207 ; CHECK-LABEL: @not_lowmask_sext_in_reg2(
1208 ; CHECK-NEXT:    [[L:%.*]] = shl i32 [[X:%.*]], 21
1209 ; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[L]], 21
1210 ; CHECK-NEXT:    call void @use32(i32 [[R]])
1211 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[R]], 4095
1212 ; CHECK-NEXT:    ret i32 [[AND]]
1214   %l = shl i32 %x, 21
1215   %r = ashr i32 %l, 21
1216   call void @use32(i32 %r)
1217   %and = and i32 %r, 4095
1218   ret i32 %and
1221 define <2 x i32> @lowmask_sext_in_reg_splat(<2 x i32> %x, <2 x i32>* %p) {
1222 ; CHECK-LABEL: @lowmask_sext_in_reg_splat(
1223 ; CHECK-NEXT:    [[L:%.*]] = shl <2 x i32> [[X:%.*]], <i32 20, i32 20>
1224 ; CHECK-NEXT:    [[R:%.*]] = ashr exact <2 x i32> [[L]], <i32 20, i32 20>
1225 ; CHECK-NEXT:    store <2 x i32> [[R]], <2 x i32>* [[P:%.*]], align 8
1226 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X]], <i32 4095, i32 4095>
1227 ; CHECK-NEXT:    ret <2 x i32> [[AND]]
1229   %l = shl <2 x i32> %x, <i32 20, i32 20>
1230   %r = ashr <2 x i32> %l, <i32 20, i32 20>
1231   store <2 x i32> %r, <2 x i32>* %p
1232   %and = and <2 x i32> %r, <i32 4095, i32 4095>
1233   ret <2 x i32> %and
1236 define i8 @lowmask_add(i8 %x) {
1237 ; CHECK-LABEL: @lowmask_add(
1238 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1239 ; CHECK-NEXT:    call void @use8(i8 [[A]])
1240 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[X]], 32
1241 ; CHECK-NEXT:    ret i8 [[R]]
1243   %a = add i8 %x, -64 ; 0xc0
1244   call void @use8(i8 %a)
1245   %r = and i8 %a, 32 ; 0x20
1246   ret i8 %r
1249 define i8 @lowmask_add_2(i8 %x) {
1250 ; CHECK-LABEL: @lowmask_add_2(
1251 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[X:%.*]], 63
1252 ; CHECK-NEXT:    ret i8 [[R]]
1254   %a = add i8 %x, -64 ; 0xc0
1255   %r = and i8 %a, 63 ; 0x3f
1256   ret i8 %r
1259 define i8 @lowmask_add_2_uses(i8 %x) {
1260 ; CHECK-LABEL: @lowmask_add_2_uses(
1261 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1262 ; CHECK-NEXT:    call void @use8(i8 [[A]])
1263 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[X]], 63
1264 ; CHECK-NEXT:    ret i8 [[R]]
1266   %a = add i8 %x, -64 ; 0xc0
1267   call void @use8(i8 %a)
1268   %r = and i8 %a, 63 ; 0x3f
1269   ret i8 %r
1272 define <2 x i8> @lowmask_add_2_splat(<2 x i8> %x, <2 x i8>* %p) {
1273 ; CHECK-LABEL: @lowmask_add_2_splat(
1274 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
1275 ; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1276 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[X]], <i8 63, i8 63>
1277 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1279   %a = add <2 x i8> %x, <i8 -64, i8 -64> ; 0xc0
1280   store <2 x i8> %a, <2 x i8>* %p
1281   %r = and <2 x i8> %a, <i8 63, i8 63> ; 0x3f
1282   ret <2 x i8> %r
1285 ; Negative test - mask overlaps low bit of add
1287 define i8 @not_lowmask_add(i8 %x) {
1288 ; CHECK-LABEL: @not_lowmask_add(
1289 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -64
1290 ; CHECK-NEXT:    call void @use8(i8 [[A]])
1291 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], 64
1292 ; CHECK-NEXT:    ret i8 [[R]]
1294   %a = add i8 %x, -64 ; 0xc0
1295   call void @use8(i8 %a)
1296   %r = and i8 %a, 64 ; 0x40
1297   ret i8 %r
1300 ; Negative test - mask overlaps low bit of add
1302 define i8 @not_lowmask_add2(i8 %x) {
1303 ; CHECK-LABEL: @not_lowmask_add2(
1304 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], -96
1305 ; CHECK-NEXT:    call void @use8(i8 [[A]])
1306 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], 63
1307 ; CHECK-NEXT:    ret i8 [[R]]
1309   %a = add i8 %x, -96 ; 0xe0
1310   call void @use8(i8 %a)
1311   %r = and i8 %a, 63 ; 0x3f
1312   ret i8 %r
1315 define <2 x i8> @lowmask_add_splat(<2 x i8> %x, <2 x i8>* %p) {
1316 ; CHECK-LABEL: @lowmask_add_splat(
1317 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
1318 ; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1319 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[X]], <i8 32, i8 32>
1320 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1322   %a = add <2 x i8> %x, <i8 -64, i8 -64> ; 0xc0
1323   store <2 x i8> %a, <2 x i8>* %p
1324   %r = and <2 x i8> %a, <i8 32, i8 32> ; 0x20
1325   ret <2 x i8> %r
1328 define <2 x i8> @lowmask_add_splat_undef(<2 x i8> %x, <2 x i8>* %p) {
1329 ; CHECK-LABEL: @lowmask_add_splat_undef(
1330 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 undef>
1331 ; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1332 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 undef, i8 32>
1333 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1335   %a = add <2 x i8> %x, <i8 -64, i8 undef> ; 0xc0
1336   store <2 x i8> %a, <2 x i8>* %p
1337   %r = and <2 x i8> %a, <i8 undef, i8 32> ; 0x20
1338   ret <2 x i8> %r
1341 define <2 x i8> @lowmask_add_vec(<2 x i8> %x, <2 x i8>* %p) {
1342 ; CHECK-LABEL: @lowmask_add_vec(
1343 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], <i8 -96, i8 -64>
1344 ; CHECK-NEXT:    store <2 x i8> [[A]], <2 x i8>* [[P:%.*]], align 2
1345 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 16, i8 32>
1346 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1348   %a = add <2 x i8> %x, <i8 -96, i8 -64> ; 0xe0, 0xc0
1349   store <2 x i8> %a, <2 x i8>* %p
1350   %r = and <2 x i8> %a, <i8 16, i8 32> ; 0x10, 0x20
1351   ret <2 x i8> %r
1354 ; Only one bit set
1355 define i8 @flip_masked_bit(i8 %A) {
1356 ; CHECK-LABEL: @flip_masked_bit(
1357 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], 16
1358 ; CHECK-NEXT:    [[C:%.*]] = xor i8 [[TMP1]], 16
1359 ; CHECK-NEXT:    ret i8 [[C]]
1361   %B = add i8 %A, 16
1362   %C = and i8 %B, 16
1363   ret i8 %C
1366 define <2 x i8> @flip_masked_bit_uniform(<2 x i8> %A) {
1367 ; CHECK-LABEL: @flip_masked_bit_uniform(
1368 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[A:%.*]], <i8 16, i8 16>
1369 ; CHECK-NEXT:    [[C:%.*]] = xor <2 x i8> [[TMP1]], <i8 16, i8 16>
1370 ; CHECK-NEXT:    ret <2 x i8> [[C]]
1372   %B = add <2 x i8> %A, <i8 16, i8 16>
1373   %C = and <2 x i8> %B, <i8 16, i8 16>
1374   ret <2 x i8> %C
1377 define <2 x i8> @flip_masked_bit_undef(<2 x i8> %A) {
1378 ; CHECK-LABEL: @flip_masked_bit_undef(
1379 ; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A:%.*]], <i8 16, i8 undef>
1380 ; CHECK-NEXT:    [[C:%.*]] = and <2 x i8> [[B]], <i8 16, i8 undef>
1381 ; CHECK-NEXT:    ret <2 x i8> [[C]]
1383   %B = add <2 x i8> %A, <i8 16, i8 undef>
1384   %C = and <2 x i8> %B, <i8 16, i8 undef>
1385   ret <2 x i8> %C
1388 define <2 x i8> @flip_masked_bit_nonuniform(<2 x i8> %A) {
1389 ; CHECK-LABEL: @flip_masked_bit_nonuniform(
1390 ; CHECK-NEXT:    [[B:%.*]] = add <2 x i8> [[A:%.*]], <i8 16, i8 4>
1391 ; CHECK-NEXT:    [[C:%.*]] = and <2 x i8> [[B]], <i8 16, i8 4>
1392 ; CHECK-NEXT:    ret <2 x i8> [[C]]
1394   %B = add <2 x i8> %A, <i8 16, i8 4>
1395   %C = and <2 x i8> %B, <i8 16, i8 4>
1396   ret <2 x i8> %C
1399 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1400 ; CHECK-LABEL: @ashr_bitwidth_mask(
1401 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i8 [[X:%.*]], 0
1402 ; CHECK-NEXT:    [[NEG_OR_ZERO:%.*]] = select i1 [[ISNEG]], i8 [[Y:%.*]], i8 0
1403 ; CHECK-NEXT:    ret i8 [[NEG_OR_ZERO]]
1405   %sign = ashr i8 %x, 7
1406   %neg_or_zero = and i8 %sign, %y
1407   ret i8 %neg_or_zero
1410 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1411 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1412 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1413 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
1414 ; CHECK-NEXT:    [[NEG_OR_ZERO:%.*]] = select <2 x i1> [[ISNEG]], <2 x i8> [[Y]], <2 x i8> zeroinitializer
1415 ; CHECK-NEXT:    ret <2 x i8> [[NEG_OR_ZERO]]
1417   %y = mul <2 x i8> %py, <i8 42, i8 2>      ; thwart complexity-based ordering
1418   %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1419   %neg_or_zero = and <2 x i8> %y, %sign
1420   ret <2 x i8> %neg_or_zero
1423 ; negative test - extra use
1425 define i8 @ashr_bitwidth_mask_use(i8 %x, i8 %y) {
1426 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1427 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1428 ; CHECK-NEXT:    call void @use8(i8 [[SIGN]])
1429 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[SIGN]], [[Y:%.*]]
1430 ; CHECK-NEXT:    ret i8 [[R]]
1432   %sign = ashr i8 %x, 7
1433   call void @use8(i8 %sign)
1434   %r = and i8 %sign, %y
1435   ret i8 %r
1438 ; negative test - wrong shift amount
1440 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1441 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1442 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1443 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[SIGN]], [[Y:%.*]]
1444 ; CHECK-NEXT:    ret i8 [[R]]
1446   %sign = ashr i8 %x, 6
1447   %r = and i8 %sign, %y
1448   ret i8 %r
1451 ; negative test - wrong shift opcode
1453 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1454 ; CHECK-LABEL: @lshr_bitwidth_mask(
1455 ; CHECK-NEXT:    [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1456 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[SIGN]], [[Y:%.*]]
1457 ; CHECK-NEXT:    ret i8 [[R]]
1459   %sign = lshr i8 %x, 7
1460   %r = and i8 %sign, %y
1461   ret i8 %r
1464 define i8 @not_ashr_bitwidth_mask(i8 %x, i8 %y) {
1465 ; CHECK-LABEL: @not_ashr_bitwidth_mask(
1466 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i8 [[X:%.*]], 0
1467 ; CHECK-NEXT:    [[POS_OR_ZERO:%.*]] = select i1 [[ISNEG]], i8 0, i8 [[Y:%.*]]
1468 ; CHECK-NEXT:    ret i8 [[POS_OR_ZERO]]
1470   %sign = ashr i8 %x, 7
1471   %not = xor i8 %sign, -1
1472   %pos_or_zero = and i8 %not, %y
1473   ret i8 %pos_or_zero
1476 define <2 x i8> @not_ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1477 ; CHECK-LABEL: @not_ashr_bitwidth_mask_vec_commute(
1478 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1479 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
1480 ; CHECK-NEXT:    [[POS_OR_ZERO:%.*]] = select <2 x i1> [[ISNEG]], <2 x i8> zeroinitializer, <2 x i8> [[Y]]
1481 ; CHECK-NEXT:    ret <2 x i8> [[POS_OR_ZERO]]
1483   %y = mul <2 x i8> %py, <i8 42, i8 2>      ; thwart complexity-based ordering
1484   %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1485   %not = xor <2 x i8> %sign, <i8 -1, i8 -1>
1486   %pos_or_zero = and <2 x i8> %y, %not
1487   ret <2 x i8> %pos_or_zero
1490 ; extra use of shift is ok
1492 define i8 @not_ashr_bitwidth_mask_use1(i8 %x, i8 %y) {
1493 ; CHECK-LABEL: @not_ashr_bitwidth_mask_use1(
1494 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1495 ; CHECK-NEXT:    call void @use8(i8 [[SIGN]])
1496 ; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i8 [[X]], 0
1497 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISNEG]], i8 0, i8 [[Y:%.*]]
1498 ; CHECK-NEXT:    ret i8 [[R]]
1500   %sign = ashr i8 %x, 7
1501   call void @use8(i8 %sign)
1502   %not = xor i8 %sign, -1
1503   %r = and i8 %not, %y
1504   ret i8 %r
1507 ; negative test - extra use
1509 define i8 @not_ashr_bitwidth_mask_use2(i8 %x, i8 %y) {
1510 ; CHECK-LABEL: @not_ashr_bitwidth_mask_use2(
1511 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1512 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[SIGN]], -1
1513 ; CHECK-NEXT:    call void @use8(i8 [[NOT]])
1514 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT]], [[Y:%.*]]
1515 ; CHECK-NEXT:    ret i8 [[R]]
1517   %sign = ashr i8 %x, 7
1518   %not = xor i8 %sign, -1
1519   call void @use8(i8 %not)
1520   %r = and i8 %not, %y
1521   ret i8 %r
1524 ; negative test - wrong shift amount
1526 define i8 @not_ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1527 ; CHECK-LABEL: @not_ashr_not_bitwidth_mask(
1528 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1529 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[SIGN]], -1
1530 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT]], [[Y:%.*]]
1531 ; CHECK-NEXT:    ret i8 [[R]]
1533   %sign = ashr i8 %x, 6
1534   %not = xor i8 %sign, -1
1535   %r = and i8 %not, %y
1536   ret i8 %r
1539 ; negative test - wrong shift opcode
1541 define i8 @not_lshr_bitwidth_mask(i8 %x, i8 %y) {
1542 ; CHECK-LABEL: @not_lshr_bitwidth_mask(
1543 ; CHECK-NEXT:    [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1544 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[SIGN]], -1
1545 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT]], [[Y:%.*]]
1546 ; CHECK-NEXT:    ret i8 [[R]]
1548   %sign = lshr i8 %x, 7
1549   %not = xor i8 %sign, -1
1550   %r = and i8 %not, %y
1551   ret i8 %r