1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4declare i32 @llvm.smax.i32(i32, i32)
5declare <2 x i32> @llvm.umin.v2i32(<2 x i32>, <2 x i32>)
6
7define i8 @and0(i8 %x) {
8; CHECK-LABEL: @and0(
9; CHECK-NEXT:    ret i8 0
10;
11  %r = and i8 %x, 0
12  ret i8 %r
13}
14
15define <2 x i8> @and0_vec_undef_elt(<2 x i8> %x) {
16; CHECK-LABEL: @and0_vec_undef_elt(
17; CHECK-NEXT:    ret <2 x i8> zeroinitializer
18;
19  %r = and <2 x i8> %x, <i8 undef, i8 0>
20  ret <2 x i8> %r
21}
22
23; add nsw (xor X, signbit), signbit --> X
24
25define <2 x i32> @add_nsw_signbit(<2 x i32> %x) {
26; CHECK-LABEL: @add_nsw_signbit(
27; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
28;
29  %y = xor <2 x i32> %x, <i32 -2147483648, i32 -2147483648>
30  %z = add nsw <2 x i32> %y, <i32 -2147483648, i32 -2147483648>
31  ret <2 x i32> %z
32}
33
34; Undef elements in either constant vector are ok.
35
36define <2 x i32> @add_nsw_signbit_undef(<2 x i32> %x) {
37; CHECK-LABEL: @add_nsw_signbit_undef(
38; CHECK-NEXT:    ret <2 x i32> [[X:%.*]]
39;
40  %y = xor <2 x i32> %x, <i32 undef, i32 -2147483648>
41  %z = add nsw <2 x i32> %y, <i32 -2147483648, i32 undef>
42  ret <2 x i32> %z
43}
44
45; add nuw (xor X, signbit), signbit --> X
46
47define <2 x i5> @add_nuw_signbit(<2 x i5> %x) {
48; CHECK-LABEL: @add_nuw_signbit(
49; CHECK-NEXT:    ret <2 x i5> [[X:%.*]]
50;
51  %y = xor <2 x i5> %x, <i5 -16, i5 -16>
52  %z = add nuw <2 x i5> %y, <i5 -16, i5 -16>
53  ret <2 x i5> %z
54}
55
56; Undef elements in either constant vector are ok.
57
58define <2 x i5> @add_nuw_signbit_undef(<2 x i5> %x) {
59; CHECK-LABEL: @add_nuw_signbit_undef(
60; CHECK-NEXT:    ret <2 x i5> [[X:%.*]]
61;
62  %y = xor <2 x i5> %x, <i5 -16, i5 undef>
63  %z = add nuw <2 x i5> %y, <i5 undef, i5 -16>
64  ret <2 x i5> %z
65}
66
67define i64 @pow2(i32 %x) {
68; CHECK-LABEL: @pow2(
69; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
70; CHECK-NEXT:    [[X2:%.*]] = and i32 [[X]], [[NEGX]]
71; CHECK-NEXT:    [[E:%.*]] = zext i32 [[X2]] to i64
72; CHECK-NEXT:    ret i64 [[E]]
73;
74  %negx = sub i32 0, %x
75  %x2 = and i32 %x, %negx
76  %e = zext i32 %x2 to i64
77  %nege = sub i64 0, %e
78  %e2 = and i64 %e, %nege
79  ret i64 %e2
80}
81
82define i64 @pow2b(i32 %x) {
83; CHECK-LABEL: @pow2b(
84; CHECK-NEXT:    [[SH:%.*]] = shl i32 2, [[X:%.*]]
85; CHECK-NEXT:    [[E:%.*]] = zext i32 [[SH]] to i64
86; CHECK-NEXT:    ret i64 [[E]]
87;
88  %sh = shl i32 2, %x
89  %e = zext i32 %sh to i64
90  %nege = sub i64 0, %e
91  %e2 = and i64 %e, %nege
92  ret i64 %e2
93}
94
95define i32 @pow2b_max(i32 %x, i32 %y) {
96; CHECK-LABEL: @pow2b_max(
97; CHECK-NEXT:    [[SHX:%.*]] = shl i32 2, [[X:%.*]]
98; CHECK-NEXT:    [[SHY:%.*]] = shl i32 32, [[Y:%.*]]
99; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[SHX]], i32 [[SHY]])
100; CHECK-NEXT:    ret i32 [[M]]
101;
102  %shx = shl i32 2, %x
103  %shy = shl i32 32, %y
104  %m = call i32 @llvm.smax.i32(i32 %shx, i32 %shy)
105  %neg = sub i32 0, %m
106  %r = and i32 %m, %neg
107  ret i32 %r
108}
109
110; Power-of-2-or-zero value has no bits in common with its decrement.
111
112define i32 @pow2_decrement(i32 %p) {
113; CHECK-LABEL: @pow2_decrement(
114; CHECK-NEXT:    ret i32 0
115;
116  %x = shl i32 1, %p
117  %a = add i32 %x, -1
118  %r = and i32 %a, %x
119  ret i32 %r
120}
121
122define <2 x i32> @pow2_decrement_commute_vec(<2 x i32> %p) {
123; CHECK-LABEL: @pow2_decrement_commute_vec(
124; CHECK-NEXT:    ret <2 x i32> zeroinitializer
125;
126  %x = and <2 x i32> %p, <i32 2048, i32 2048>
127  %a = add <2 x i32> %x, <i32 -1, i32 -1>
128  %r = and <2 x i32> %x, %a
129  ret <2 x i32> %r
130}
131
132define <2 x i32> @pow2_decrement_min_vec(<2 x i32> %x, <2 x i32> %y) {
133; CHECK-LABEL: @pow2_decrement_min_vec(
134; CHECK-NEXT:    ret <2 x i32> zeroinitializer
135;
136  %p1 = and <2 x i32> %x, <i32 2048, i32 2048>
137  %p2 = shl <2 x i32> <i32 1, i32 1>, %y
138  %m = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %p1, <2 x i32> %p2)
139  %a = add <2 x i32> %m, <i32 -1, i32 -1>
140  %r = and <2 x i32> %m, %a
141  ret <2 x i32> %r
142}
143
144define i1 @and_of_icmps0(i32 %b) {
145; CHECK-LABEL: @and_of_icmps0(
146; CHECK-NEXT:    ret i1 false
147;
148  %1 = add i32 %b, 2
149  %2 = icmp ult i32 %1, 4
150  %cmp3 = icmp sgt i32 %b, 2
151  %cmp = and i1 %2, %cmp3
152  ret i1 %cmp
153}
154
155define <2 x i1> @and_of_icmps0_vec(<2 x i32> %b) {
156; CHECK-LABEL: @and_of_icmps0_vec(
157; CHECK-NEXT:    ret <2 x i1> zeroinitializer
158;
159  %1 = add <2 x i32> %b, <i32 2, i32 2>
160  %2 = icmp ult <2 x i32> %1, <i32 4, i32 4>
161  %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2>
162  %cmp = and <2 x i1> %2, %cmp3
163  ret <2 x i1> %cmp
164}
165
166define i1 @and_of_icmps1(i32 %b) {
167; CHECK-LABEL: @and_of_icmps1(
168; CHECK-NEXT:    ret i1 false
169;
170  %1 = add nsw i32 %b, 2
171  %2 = icmp slt i32 %1, 4
172  %cmp3 = icmp sgt i32 %b, 2
173  %cmp = and i1 %2, %cmp3
174  ret i1 %cmp
175}
176
177define <2 x i1> @and_of_icmps1_vec(<2 x i32> %b) {
178; CHECK-LABEL: @and_of_icmps1_vec(
179; CHECK-NEXT:    ret <2 x i1> zeroinitializer
180;
181  %1 = add nsw <2 x i32> %b, <i32 2, i32 2>
182  %2 = icmp slt <2 x i32> %1, <i32 4, i32 4>
183  %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2>
184  %cmp = and <2 x i1> %2, %cmp3
185  ret <2 x i1> %cmp
186}
187
188define i1 @and_of_icmps2(i32 %b) {
189; CHECK-LABEL: @and_of_icmps2(
190; CHECK-NEXT:    ret i1 false
191;
192  %1 = add i32 %b, 2
193  %2 = icmp ule i32 %1, 3
194  %cmp3 = icmp sgt i32 %b, 2
195  %cmp = and i1 %2, %cmp3
196  ret i1 %cmp
197}
198
199define <2 x i1> @and_of_icmps2_vec(<2 x i32> %b) {
200; CHECK-LABEL: @and_of_icmps2_vec(
201; CHECK-NEXT:    ret <2 x i1> zeroinitializer
202;
203  %1 = add <2 x i32> %b, <i32 2, i32 2>
204  %2 = icmp ule <2 x i32> %1, <i32 3, i32 3>
205  %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2>
206  %cmp = and <2 x i1> %2, %cmp3
207  ret <2 x i1> %cmp
208}
209
210define i1 @and_of_icmps3(i32 %b) {
211; CHECK-LABEL: @and_of_icmps3(
212; CHECK-NEXT:    ret i1 false
213;
214  %1 = add nsw i32 %b, 2
215  %2 = icmp sle i32 %1, 3
216  %cmp3 = icmp sgt i32 %b, 2
217  %cmp = and i1 %2, %cmp3
218  ret i1 %cmp
219}
220
221define <2 x i1> @and_of_icmps3_vec(<2 x i32> %b) {
222; CHECK-LABEL: @and_of_icmps3_vec(
223; CHECK-NEXT:    ret <2 x i1> zeroinitializer
224;
225  %1 = add nsw <2 x i32> %b, <i32 2, i32 2>
226  %2 = icmp sle <2 x i32> %1, <i32 3, i32 3>
227  %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2>
228  %cmp = and <2 x i1> %2, %cmp3
229  ret <2 x i1> %cmp
230}
231
232define i1 @and_of_icmps4(i32 %b) {
233; CHECK-LABEL: @and_of_icmps4(
234; CHECK-NEXT:    ret i1 false
235;
236  %1 = add nuw i32 %b, 2
237  %2 = icmp ult i32 %1, 4
238  %cmp3 = icmp ugt i32 %b, 2
239  %cmp = and i1 %2, %cmp3
240  ret i1 %cmp
241}
242
243define <2 x i1> @and_of_icmps4_vec(<2 x i32> %b) {
244; CHECK-LABEL: @and_of_icmps4_vec(
245; CHECK-NEXT:    ret <2 x i1> zeroinitializer
246;
247  %1 = add nuw <2 x i32> %b, <i32 2, i32 2>
248  %2 = icmp ult <2 x i32> %1, <i32 4, i32 4>
249  %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2>
250  %cmp = and <2 x i1> %2, %cmp3
251  ret <2 x i1> %cmp
252}
253
254define i1 @and_of_icmps5(i32 %b) {
255; CHECK-LABEL: @and_of_icmps5(
256; CHECK-NEXT:    ret i1 false
257;
258  %1 = add nuw i32 %b, 2
259  %2 = icmp ule i32 %1, 3
260  %cmp3 = icmp ugt i32 %b, 2
261  %cmp = and i1 %2, %cmp3
262  ret i1 %cmp
263}
264
265define <2 x i1> @and_of_icmps5_vec(<2 x i32> %b) {
266; CHECK-LABEL: @and_of_icmps5_vec(
267; CHECK-NEXT:    ret <2 x i1> zeroinitializer
268;
269  %1 = add nuw <2 x i32> %b, <i32 2, i32 2>
270  %2 = icmp ule <2 x i32> %1, <i32 3, i32 3>
271  %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2>
272  %cmp = and <2 x i1> %2, %cmp3
273  ret <2 x i1> %cmp
274}
275
276define i1 @or_of_icmps0(i32 %b) {
277; CHECK-LABEL: @or_of_icmps0(
278; CHECK-NEXT:    ret i1 true
279;
280  %1 = add i32 %b, 2
281  %2 = icmp uge i32 %1, 4
282  %cmp3 = icmp sle i32 %b, 2
283  %cmp = or i1 %2, %cmp3
284  ret i1 %cmp
285}
286
287define <2 x i1> @or_of_icmps0_vec(<2 x i32> %b) {
288; CHECK-LABEL: @or_of_icmps0_vec(
289; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
290;
291  %1 = add <2 x i32> %b, <i32 2, i32 2>
292  %2 = icmp uge <2 x i32> %1, <i32 4, i32 4>
293  %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2>
294  %cmp = or <2 x i1> %2, %cmp3
295  ret <2 x i1> %cmp
296}
297
298define i1 @or_of_icmps1(i32 %b) {
299; CHECK-LABEL: @or_of_icmps1(
300; CHECK-NEXT:    ret i1 true
301;
302  %1 = add nsw i32 %b, 2
303  %2 = icmp sge i32 %1, 4
304  %cmp3 = icmp sle i32 %b, 2
305  %cmp = or i1 %2, %cmp3
306  ret i1 %cmp
307}
308
309define <2 x i1> @or_of_icmps1_vec(<2 x i32> %b) {
310; CHECK-LABEL: @or_of_icmps1_vec(
311; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
312;
313  %1 = add nsw <2 x i32> %b, <i32 2, i32 2>
314  %2 = icmp sge <2 x i32> %1, <i32 4, i32 4>
315  %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2>
316  %cmp = or <2 x i1> %2, %cmp3
317  ret <2 x i1> %cmp
318}
319
320define i1 @or_of_icmps2(i32 %b) {
321; CHECK-LABEL: @or_of_icmps2(
322; CHECK-NEXT:    ret i1 true
323;
324  %1 = add i32 %b, 2
325  %2 = icmp ugt i32 %1, 3
326  %cmp3 = icmp sle i32 %b, 2
327  %cmp = or i1 %2, %cmp3
328  ret i1 %cmp
329}
330
331define <2 x i1> @or_of_icmps2_vec(<2 x i32> %b) {
332; CHECK-LABEL: @or_of_icmps2_vec(
333; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
334;
335  %1 = add <2 x i32> %b, <i32 2, i32 2>
336  %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3>
337  %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2>
338  %cmp = or <2 x i1> %2, %cmp3
339  ret <2 x i1> %cmp
340}
341
342define i1 @or_of_icmps3(i32 %b) {
343; CHECK-LABEL: @or_of_icmps3(
344; CHECK-NEXT:    ret i1 true
345;
346  %1 = add nsw i32 %b, 2
347  %2 = icmp sgt i32 %1, 3
348  %cmp3 = icmp sle i32 %b, 2
349  %cmp = or i1 %2, %cmp3
350  ret i1 %cmp
351}
352
353define <2 x i1> @or_of_icmps3_vec(<2 x i32> %b) {
354; CHECK-LABEL: @or_of_icmps3_vec(
355; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
356;
357  %1 = add nsw <2 x i32> %b, <i32 2, i32 2>
358  %2 = icmp sgt <2 x i32> %1, <i32 3, i32 3>
359  %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2>
360  %cmp = or <2 x i1> %2, %cmp3
361  ret <2 x i1> %cmp
362}
363
364define i1 @or_of_icmps4(i32 %b) {
365; CHECK-LABEL: @or_of_icmps4(
366; CHECK-NEXT:    ret i1 true
367;
368  %1 = add nuw i32 %b, 2
369  %2 = icmp uge i32 %1, 4
370  %cmp3 = icmp ule i32 %b, 2
371  %cmp = or i1 %2, %cmp3
372  ret i1 %cmp
373}
374
375define <2 x i1> @or_of_icmps4_vec(<2 x i32> %b) {
376; CHECK-LABEL: @or_of_icmps4_vec(
377; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
378;
379  %1 = add nuw <2 x i32> %b, <i32 2, i32 2>
380  %2 = icmp uge <2 x i32> %1, <i32 4, i32 4>
381  %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2>
382  %cmp = or <2 x i1> %2, %cmp3
383  ret <2 x i1> %cmp
384}
385
386define i1 @or_of_icmps5(i32 %b) {
387; CHECK-LABEL: @or_of_icmps5(
388; CHECK-NEXT:    ret i1 true
389;
390  %1 = add nuw i32 %b, 2
391  %2 = icmp ugt i32 %1, 3
392  %cmp3 = icmp ule i32 %b, 2
393  %cmp = or i1 %2, %cmp3
394  ret i1 %cmp
395}
396
397define <2 x i1> @or_of_icmps5_vec(<2 x i32> %b) {
398; CHECK-LABEL: @or_of_icmps5_vec(
399; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
400;
401  %1 = add nuw <2 x i32> %b, <i32 2, i32 2>
402  %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3>
403  %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2>
404  %cmp = or <2 x i1> %2, %cmp3
405  ret <2 x i1> %cmp
406}
407
408define i32 @neg_nuw(i32 %x) {
409; CHECK-LABEL: @neg_nuw(
410; CHECK-NEXT:    ret i32 0
411;
412  %neg = sub nuw i32 0, %x
413  ret i32 %neg
414}
415
416; PR27869 - Look through casts to eliminate cmps and bitwise logic.
417
418define i32 @and_of_zexted_icmps(i32 %i) {
419; CHECK-LABEL: @and_of_zexted_icmps(
420; CHECK-NEXT:    ret i32 0
421;
422  %cmp0 = icmp eq i32 %i, 0
423  %conv0 = zext i1 %cmp0 to i32
424  %cmp1 = icmp ugt i32 %i, 4
425  %conv1 = zext i1 %cmp1 to i32
426  %and = and i32 %conv0, %conv1
427  ret i32 %and
428}
429
430; Make sure vectors work too.
431
432define <4 x i32> @and_of_zexted_icmps_vec(<4 x i32> %i) {
433; CHECK-LABEL: @and_of_zexted_icmps_vec(
434; CHECK-NEXT:    ret <4 x i32> zeroinitializer
435;
436  %cmp0 = icmp eq <4 x i32> %i, zeroinitializer
437  %conv0 = zext <4 x i1> %cmp0 to <4 x i32>
438  %cmp1 = icmp slt <4 x i32> %i, zeroinitializer
439  %conv1 = zext <4 x i1> %cmp1 to <4 x i32>
440  %and = and <4 x i32> %conv0, %conv1
441  ret <4 x i32> %and
442}
443
444; Try a different cast and weird types.
445
446define i5 @and_of_sexted_icmps(i3 %i) {
447; CHECK-LABEL: @and_of_sexted_icmps(
448; CHECK-NEXT:    ret i5 0
449;
450  %cmp0 = icmp eq i3 %i, 0
451  %conv0 = sext i1 %cmp0 to i5
452  %cmp1 = icmp ugt i3 %i, 1
453  %conv1 = sext i1 %cmp1 to i5
454  %and = and i5 %conv0, %conv1
455  ret i5 %and
456}
457
458; Try a different cast and weird vector types.
459
460define i3 @and_of_bitcast_icmps_vec(<3 x i65> %i) {
461; CHECK-LABEL: @and_of_bitcast_icmps_vec(
462; CHECK-NEXT:    ret i3 0
463;
464  %cmp0 = icmp sgt <3 x i65> %i, zeroinitializer
465  %conv0 = bitcast <3 x i1> %cmp0 to i3
466  %cmp1 = icmp slt <3 x i65> %i, zeroinitializer
467  %conv1 = bitcast <3 x i1> %cmp1 to i3
468  %and = and i3 %conv0, %conv1
469  ret i3 %and
470}
471
472; We can't do this if the casts are different.
473
474define i16 @and_of_different_cast_icmps(i8 %i) {
475; CHECK-LABEL: @and_of_different_cast_icmps(
476; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i8 [[I:%.*]], 0
477; CHECK-NEXT:    [[CONV0:%.*]] = zext i1 [[CMP0]] to i16
478; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[I]], 1
479; CHECK-NEXT:    [[CONV1:%.*]] = sext i1 [[CMP1]] to i16
480; CHECK-NEXT:    [[AND:%.*]] = and i16 [[CONV0]], [[CONV1]]
481; CHECK-NEXT:    ret i16 [[AND]]
482;
483  %cmp0 = icmp eq i8 %i, 0
484  %conv0 = zext i1 %cmp0 to i16
485  %cmp1 = icmp eq i8 %i, 1
486  %conv1 = sext i1 %cmp1 to i16
487  %and = and i16 %conv0, %conv1
488  ret i16 %and
489}
490
491define <2 x i3> @and_of_different_cast_icmps_vec(<2 x i8> %i, <2 x i16> %j) {
492; CHECK-LABEL: @and_of_different_cast_icmps_vec(
493; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq <2 x i8> [[I:%.*]], zeroinitializer
494; CHECK-NEXT:    [[CONV0:%.*]] = zext <2 x i1> [[CMP0]] to <2 x i3>
495; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt <2 x i16> [[J:%.*]], <i16 1, i16 1>
496; CHECK-NEXT:    [[CONV1:%.*]] = zext <2 x i1> [[CMP1]] to <2 x i3>
497; CHECK-NEXT:    [[AND:%.*]] = and <2 x i3> [[CONV0]], [[CONV1]]
498; CHECK-NEXT:    ret <2 x i3> [[AND]]
499;
500  %cmp0 = icmp eq <2 x i8> %i, zeroinitializer
501  %conv0 = zext <2 x i1> %cmp0 to <2 x i3>
502  %cmp1 = icmp ugt <2 x i16> %j, <i16 1, i16 1>
503  %conv1 = zext <2 x i1> %cmp1 to <2 x i3>
504  %and = and <2 x i3> %conv0, %conv1
505  ret <2 x i3> %and
506}
507
508; limit
509
510define i32 @or_of_zexted_icmps(i32 %i) {
511; CHECK-LABEL: @or_of_zexted_icmps(
512; CHECK-NEXT:    ret i32 1
513;
514  %cmp0 = icmp ne i32 %i, 0
515  %conv0 = zext i1 %cmp0 to i32
516  %cmp1 = icmp uge i32 4, %i
517  %conv1 = zext i1 %cmp1 to i32
518  %or = or i32 %conv0, %conv1
519  ret i32 %or
520}
521
522; Try a different cast and weird vector types.
523
524define i3 @or_of_bitcast_icmps_vec(<3 x i65> %i) {
525; CHECK-LABEL: @or_of_bitcast_icmps_vec(
526; CHECK-NEXT:    ret i3 bitcast (<3 x i1> <i1 true, i1 true, i1 true> to i3)
527;
528  %cmp0 = icmp sge <3 x i65> %i, zeroinitializer
529  %conv0 = bitcast <3 x i1> %cmp0 to i3
530  %cmp1 = icmp slt <3 x i65> %i, zeroinitializer
531  %conv1 = bitcast <3 x i1> %cmp1 to i3
532  %or = or i3 %conv0, %conv1
533  ret i3 %or
534}
535
536; We can't simplify if the casts are different.
537
538define i16 @or_of_different_cast_icmps(i8 %i) {
539; CHECK-LABEL: @or_of_different_cast_icmps(
540; CHECK-NEXT:    [[CMP0:%.*]] = icmp ne i8 [[I:%.*]], 0
541; CHECK-NEXT:    [[CONV0:%.*]] = zext i1 [[CMP0]] to i16
542; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[I]], 1
543; CHECK-NEXT:    [[CONV1:%.*]] = sext i1 [[CMP1]] to i16
544; CHECK-NEXT:    [[OR:%.*]] = or i16 [[CONV0]], [[CONV1]]
545; CHECK-NEXT:    ret i16 [[OR]]
546;
547  %cmp0 = icmp ne i8 %i, 0
548  %conv0 = zext i1 %cmp0 to i16
549  %cmp1 = icmp ne i8 %i, 1
550  %conv1 = sext i1 %cmp1 to i16
551  %or = or i16 %conv0, %conv1
552  ret i16 %or
553}
554
555; (A & ~B) | (A ^ B) -> A ^ B
556
557define i32 @test43(i32 %a, i32 %b) {
558; CHECK-LABEL: @test43(
559; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
560; CHECK-NEXT:    ret i32 [[XOR]]
561;
562  %neg = xor i32 %b, -1
563  %and = and i32 %a, %neg
564  %xor = xor i32 %a, %b
565  %or = or i32 %and, %xor
566  ret i32 %or
567}
568
569define i32 @test43_commuted_and(i32 %a, i32 %b) {
570; CHECK-LABEL: @test43_commuted_and(
571; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
572; CHECK-NEXT:    ret i32 [[XOR]]
573;
574  %neg = xor i32 %b, -1
575  %and = and i32 %neg, %a
576  %xor = xor i32 %a, %b
577  %or = or i32 %and, %xor
578  ret i32 %or
579}
580
581; Commute operands of the 'or'.
582; (A ^ B) | (A & ~B) -> A ^ B
583
584define i32 @test44(i32 %a, i32 %b) {
585; CHECK-LABEL: @test44(
586; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
587; CHECK-NEXT:    ret i32 [[XOR]]
588;
589  %xor = xor i32 %a, %b
590  %neg = xor i32 %b, -1
591  %and = and i32 %a, %neg
592  %or = or i32 %xor, %and
593  ret i32 %or
594}
595
596define i32 @test44_commuted_and(i32 %a, i32 %b) {
597; CHECK-LABEL: @test44_commuted_and(
598; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
599; CHECK-NEXT:    ret i32 [[XOR]]
600;
601  %xor = xor i32 %a, %b
602  %neg = xor i32 %b, -1
603  %and = and i32 %neg, %a
604  %or = or i32 %xor, %and
605  ret i32 %or
606}
607
608; (~A & ~B) | (~A ^ B) -> ~A ^ B
609
610define i32 @test45(i32 %a, i32 %b) {
611; CHECK-LABEL: @test45(
612; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
613; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
614; CHECK-NEXT:    ret i32 [[XOR]]
615;
616  %nega = xor i32 %a, -1
617  %negb = xor i32 %b, -1
618  %and = and i32 %nega, %negb
619  %xor = xor i32 %a, %negb
620  %or = or i32 %and, %xor
621  ret i32 %or
622}
623
624define i32 @test45_commuted_and(i32 %a, i32 %b) {
625; CHECK-LABEL: @test45_commuted_and(
626; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
627; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
628; CHECK-NEXT:    ret i32 [[XOR]]
629;
630  %nega = xor i32 %a, -1
631  %negb = xor i32 %b, -1
632  %and = and i32 %negb, %nega
633  %xor = xor i32 %a, %negb
634  %or = or i32 %and, %xor
635  ret i32 %or
636}
637
638; Commute operands of the 'or'.
639; (~A ^ B) | (~A & ~B) -> ~A ^ B
640
641define i32 @test46(i32 %a, i32 %b) {
642; CHECK-LABEL: @test46(
643; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
644; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
645; CHECK-NEXT:    ret i32 [[XOR]]
646;
647  %nega = xor i32 %a, -1
648  %negb = xor i32 %b, -1
649  %and = and i32 %nega, %negb
650  %xor = xor i32 %a, %negb
651  %or = or i32 %xor, %and
652  ret i32 %or
653}
654
655; (~A & ~B) | (~A ^ B) -> ~A ^ B
656
657define i32 @test46_commuted_and(i32 %a, i32 %b) {
658; CHECK-LABEL: @test46_commuted_and(
659; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
660; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
661; CHECK-NEXT:    ret i32 [[XOR]]
662;
663  %nega = xor i32 %a, -1
664  %negb = xor i32 %b, -1
665  %and = and i32 %negb, %nega
666  %xor = xor i32 %a, %negb
667  %or = or i32 %xor, %and
668  ret i32 %or
669}
670
671; (~A ^ B) | (A & B) -> ~A ^ B
672
673define i32 @test47(i32 %a, i32 %b) {
674; CHECK-LABEL: @test47(
675; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
676; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
677; CHECK-NEXT:    ret i32 [[XOR]]
678;
679  %nega = xor i32 %a, -1
680  %and = and i32 %a, %b
681  %xor = xor i32 %nega, %b
682  %or = or i32 %xor, %and
683  ret i32 %or
684}
685
686define i32 @test48(i32 %a, i32 %b) {
687; CHECK-LABEL: @test48(
688; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
689; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
690; CHECK-NEXT:    ret i32 [[XOR]]
691;
692  %nega = xor i32 %a, -1
693  %and = and i32 %a, %b
694  %xor = xor i32 %b, %nega
695  %or = or i32 %xor, %and
696  ret i32 %or
697}
698
699define i32 @test49(i32 %a, i32 %b) {
700; CHECK-LABEL: @test49(
701; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
702; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
703; CHECK-NEXT:    ret i32 [[XOR]]
704;
705  %nega = xor i32 %a, -1
706  %and = and i32 %b, %a
707  %xor = xor i32 %b, %nega
708  %or = or i32 %xor, %and
709  ret i32 %or
710}
711
712define i32 @test50(i32 %a, i32 %b) {
713; CHECK-LABEL: @test50(
714; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
715; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
716; CHECK-NEXT:    ret i32 [[XOR]]
717;
718  %nega = xor i32 %a, -1
719  %and = and i32 %b, %a
720  %xor = xor i32 %nega, %b
721  %or = or i32 %xor, %and
722  ret i32 %or
723}
724
725define i32 @test51(i32 %a, i32 %b) {
726; CHECK-LABEL: @test51(
727; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
728; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
729; CHECK-NEXT:    ret i32 [[XOR]]
730;
731  %nega = xor i32 %a, -1
732  %and = and i32 %a, %b
733  %xor = xor i32 %nega, %b
734  %or = or i32 %and, %xor
735  ret i32 %or
736}
737
738define i32 @test52(i32 %a, i32 %b) {
739; CHECK-LABEL: @test52(
740; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
741; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
742; CHECK-NEXT:    ret i32 [[XOR]]
743;
744  %nega = xor i32 %a, -1
745  %and = and i32 %a, %b
746  %xor = xor i32 %b, %nega
747  %or = or i32 %and, %xor
748  ret i32 %or
749}
750
751define i32 @test53(i32 %a, i32 %b) {
752; CHECK-LABEL: @test53(
753; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
754; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
755; CHECK-NEXT:    ret i32 [[XOR]]
756;
757  %nega = xor i32 %a, -1
758  %and = and i32 %b, %a
759  %xor = xor i32 %b, %nega
760  %or = or i32 %and, %xor
761  ret i32 %or
762}
763
764define i32 @test54(i32 %a, i32 %b) {
765; CHECK-LABEL: @test54(
766; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
767; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
768; CHECK-NEXT:    ret i32 [[XOR]]
769;
770  %nega = xor i32 %a, -1
771  %and = and i32 %b, %a
772  %xor = xor i32 %nega, %b
773  %or = or i32 %and, %xor
774  ret i32 %or
775}
776
777; (A & B) | ~(A ^ B) -> ~(A ^ B)
778
779define i32 @test55(i32 %a, i32 %b) {
780; CHECK-LABEL: @test55(
781; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
782; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
783; CHECK-NEXT:    [[XNOR:%.*]] = xor i32 [[XOR]], -1
784; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XNOR]]
785; CHECK-NEXT:    ret i32 [[OR]]
786;
787  %and = and i32 %a, %b
788  %xor = xor i32 %a, %b
789  %xnor = xor i32 %xor, -1
790  %or = or i32 %and, %xnor
791  ret i32 %or
792}
793
794; ~(A ^ B) | (A & B) -> ~(A ^ B)
795
796define i32 @test56(i32 %a, i32 %b) {
797; CHECK-LABEL: @test56(
798; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
799; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
800; CHECK-NEXT:    [[XNOR:%.*]] = xor i32 [[XOR]], -1
801; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XNOR]], [[AND]]
802; CHECK-NEXT:    ret i32 [[OR]]
803;
804  %and = and i32 %a, %b
805  %xor = xor i32 %a, %b
806  %xnor = xor i32 %xor, -1
807  %or = or i32 %xnor, %and
808  ret i32 %or
809}
810
811; (B & A) | ~(A ^ B) -> ~(A ^ B)
812
813define i32 @test57(i32 %a, i32 %b) {
814; CHECK-LABEL: @test57(
815; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
816; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
817; CHECK-NEXT:    [[XNOR:%.*]] = xor i32 [[XOR]], -1
818; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XNOR]]
819; CHECK-NEXT:    ret i32 [[OR]]
820;
821  %and = and i32 %b, %a
822  %xor = xor i32 %a, %b
823  %xnor = xor i32 %xor, -1
824  %or = or i32 %and, %xnor
825  ret i32 %or
826}
827
828; ~(A ^ B) | (A & B) -> ~(A ^ B)
829
830define i32 @test58(i32 %a, i32 %b) {
831; CHECK-LABEL: @test58(
832; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
833; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
834; CHECK-NEXT:    [[XNOR:%.*]] = xor i32 [[XOR]], -1
835; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XNOR]], [[AND]]
836; CHECK-NEXT:    ret i32 [[OR]]
837;
838  %and = and i32 %b, %a
839  %xor = xor i32 %a, %b
840  %xnor = xor i32 %xor, -1
841  %or = or i32 %xnor, %and
842  ret i32 %or
843}
844
845define i8 @lshr_perfect_mask(i8 %x) {
846; CHECK-LABEL: @lshr_perfect_mask(
847; CHECK-NEXT:    [[SH:%.*]] = lshr i8 [[X:%.*]], 5
848; CHECK-NEXT:    ret i8 [[SH]]
849;
850  %sh = lshr i8 %x, 5
851  %mask = and i8 %sh, 7  ; 0x07
852  ret i8 %mask
853}
854
855define <2 x i8> @lshr_oversized_mask_splat(<2 x i8> %x) {
856; CHECK-LABEL: @lshr_oversized_mask_splat(
857; CHECK-NEXT:    [[SH:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 5, i8 5>
858; CHECK-NEXT:    ret <2 x i8> [[SH]]
859;
860  %sh = lshr <2 x i8> %x, <i8 5, i8 5>
861  %mask = and <2 x i8> %sh, <i8 135, i8 135>  ; 0x87
862  ret <2 x i8> %mask
863}
864
865define i8 @lshr_undersized_mask(i8 %x) {
866; CHECK-LABEL: @lshr_undersized_mask(
867; CHECK-NEXT:    [[SH:%.*]] = lshr i8 [[X:%.*]], 5
868; CHECK-NEXT:    [[MASK:%.*]] = and i8 [[SH]], -2
869; CHECK-NEXT:    ret i8 [[MASK]]
870;
871  %sh = lshr i8 %x, 5
872  %mask = and i8 %sh, -2  ; 0xFE
873  ret i8 %mask
874}
875
876define <2 x i8> @shl_perfect_mask_splat(<2 x i8> %x) {
877; CHECK-LABEL: @shl_perfect_mask_splat(
878; CHECK-NEXT:    [[SH:%.*]] = shl <2 x i8> [[X:%.*]], <i8 6, i8 6>
879; CHECK-NEXT:    ret <2 x i8> [[SH]]
880;
881  %sh = shl <2 x i8> %x, <i8 6, i8 6>
882  %mask = and <2 x i8> %sh, <i8 192, i8 192>  ; 0xC0
883  ret <2 x i8> %mask
884}
885
886define i8 @shl_oversized_mask(i8 %x) {
887; CHECK-LABEL: @shl_oversized_mask(
888; CHECK-NEXT:    [[SH:%.*]] = shl i8 [[X:%.*]], 6
889; CHECK-NEXT:    ret i8 [[SH]]
890;
891  %sh = shl i8 %x, 6
892  %mask = and i8 %sh, 195  ; 0xC3
893  ret i8 %mask
894}
895
896define <2 x i8> @shl_undersized_mask_splat(<2 x i8> %x) {
897; CHECK-LABEL: @shl_undersized_mask_splat(
898; CHECK-NEXT:    [[SH:%.*]] = shl <2 x i8> [[X:%.*]], <i8 6, i8 6>
899; CHECK-NEXT:    [[MASK:%.*]] = and <2 x i8> [[SH]], <i8 -120, i8 -120>
900; CHECK-NEXT:    ret <2 x i8> [[MASK]]
901;
902  %sh = shl <2 x i8> %x, <i8 6, i8 6>
903  %mask = and <2 x i8> %sh, <i8 136, i8 136>  ; 0x88
904  ret <2 x i8> %mask
905}
906
907define i32 @reversed_not(i32 %a) {
908; CHECK-LABEL: @reversed_not(
909; CHECK-NEXT:    ret i32 -1
910;
911  %nega = xor i32 -1, %a
912  %or = or i32 %a, %nega
913  ret i32 %or
914}
915
916define i64 @shl_or_and1(i32 %a, i1 %b) {
917; CHECK-LABEL: @shl_or_and1(
918; CHECK-NEXT:    [[T2:%.*]] = zext i1 [[B:%.*]] to i64
919; CHECK-NEXT:    ret i64 [[T2]]
920;
921  %t1 = zext i32 %a to i64
922  %t2 = zext i1 %b to i64
923  %t3 = shl nuw i64 %t1, 32
924  %t4 = or i64 %t2, %t3
925  %t5 = and i64 %t4, 1
926  ret i64 %t5
927}
928
929define i64 @shl_or_and2(i32 %a, i1 %b) {
930; CHECK-LABEL: @shl_or_and2(
931; CHECK-NEXT:    [[T1:%.*]] = zext i1 [[B:%.*]] to i64
932; CHECK-NEXT:    [[T3:%.*]] = shl nuw i64 [[T1]], 32
933; CHECK-NEXT:    ret i64 [[T3]]
934;
935  %t1 = zext i1 %b to i64
936  %t2 = zext i32 %a to i64
937  %t3 = shl nuw i64 %t1, 32
938  %t4 = or i64 %t2, %t3
939  %t5 = and i64 %t4, 4294967296
940  ret i64 %t5
941}
942
943; concatenate two 32-bit integers and extract lower 32-bit
944define i64 @shl_or_and3(i32 %a, i32 %b) {
945; CHECK-LABEL: @shl_or_and3(
946; CHECK-NEXT:    [[T2:%.*]] = zext i32 [[B:%.*]] to i64
947; CHECK-NEXT:    ret i64 [[T2]]
948;
949  %t1 = zext i32 %a to i64
950  %t2 = zext i32 %b to i64
951  %t3 = shl nuw i64 %t1, 32
952  %t4 = or i64 %t2, %t3
953  %t5 = and i64 %t4, 4294967295
954  ret i64 %t5
955}
956
957; concatenate two 16-bit integers and extract higher 16-bit
958define i32 @shl_or_and4(i16 %a, i16 %b) {
959; CHECK-LABEL: @shl_or_and4(
960; CHECK-NEXT:    [[T1:%.*]] = zext i16 [[A:%.*]] to i32
961; CHECK-NEXT:    [[T3:%.*]] = shl nuw i32 [[T1]], 16
962; CHECK-NEXT:    ret i32 [[T3]]
963;
964  %t1 = zext i16 %a to i32
965  %t2 = zext i16 %b to i32
966  %t3 = shl nuw i32 %t1, 16
967  %t4 = or i32 %t2, %t3
968  %t5 = and i32 %t4, 4294901760 ; mask with 0xFFFF0000
969  ret i32 %t5
970}
971
972define i128 @shl_or_and5(i64 %a, i1 %b) {
973; CHECK-LABEL: @shl_or_and5(
974; CHECK-NEXT:    [[T2:%.*]] = zext i1 [[B:%.*]] to i128
975; CHECK-NEXT:    ret i128 [[T2]]
976;
977  %t1 = zext i64 %a to i128
978  %t2 = zext i1 %b to i128
979  %t3 = shl nuw i128 %t1, 64
980  %t4 = or i128 %t2, %t3
981  %t5 = and i128 %t4, 1
982  ret i128 %t5
983}
984
985; A variation of above test cases; it fails due to the mask value
986define i32 @shl_or_and6(i16 %a, i16 %b) {
987; CHECK-LABEL: @shl_or_and6(
988; CHECK-NEXT:    [[T1:%.*]] = zext i16 [[A:%.*]] to i32
989; CHECK-NEXT:    [[T2:%.*]] = zext i16 [[B:%.*]] to i32
990; CHECK-NEXT:    [[T3:%.*]] = shl nuw i32 [[T1]], 16
991; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]
992; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], -65535
993; CHECK-NEXT:    ret i32 [[T5]]
994;
995  %t1 = zext i16 %a to i32
996  %t2 = zext i16 %b to i32
997  %t3 = shl nuw i32 %t1, 16
998  %t4 = or i32 %t2, %t3
999  %t5 = and i32 %t4, 4294901761 ; mask with 0xFFFF0001
1000  ret i32 %t5
1001}
1002
1003; A variation of above test cases; it fails due to the mask value
1004define i32 @shl_or_and7(i16 %a, i16 %b) {
1005; CHECK-LABEL: @shl_or_and7(
1006; CHECK-NEXT:    [[T1:%.*]] = zext i16 [[A:%.*]] to i32
1007; CHECK-NEXT:    [[T2:%.*]] = zext i16 [[B:%.*]] to i32
1008; CHECK-NEXT:    [[T3:%.*]] = shl nuw i32 [[T1]], 16
1009; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]
1010; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], -131072
1011; CHECK-NEXT:    ret i32 [[T5]]
1012;
1013  %t1 = zext i16 %a to i32
1014  %t2 = zext i16 %b to i32
1015  %t3 = shl nuw i32 %t1, 16
1016  %t4 = or i32 %t2, %t3
1017  %t5 = and i32 %t4, 4294836224 ; mask with 0xFFFE0000
1018  ret i32 %t5
1019}
1020
1021; A variation of above test cases; it fails due to the mask value
1022define i32 @shl_or_and8(i16 %a, i16 %b) {
1023; CHECK-LABEL: @shl_or_and8(
1024; CHECK-NEXT:    [[T1:%.*]] = zext i16 [[A:%.*]] to i32
1025; CHECK-NEXT:    [[T2:%.*]] = zext i16 [[B:%.*]] to i32
1026; CHECK-NEXT:    [[T3:%.*]] = shl nuw i32 [[T1]], 16
1027; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]
1028; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 131071
1029; CHECK-NEXT:    ret i32 [[T5]]
1030;
1031  %t1 = zext i16 %a to i32
1032  %t2 = zext i16 %b to i32
1033  %t3 = shl nuw i32 %t1, 16
1034  %t4 = or i32 %t2, %t3
1035  %t5 = and i32 %t4, 131071 ; mask with 0x1FFFF
1036  ret i32 %t5
1037}
1038
1039define <2 x i64> @shl_or_and1v(<2 x i32> %a, <2 x i1> %b) {
1040; CHECK-LABEL: @shl_or_and1v(
1041; CHECK-NEXT:    [[T2:%.*]] = zext <2 x i1> [[B:%.*]] to <2 x i64>
1042; CHECK-NEXT:    ret <2 x i64> [[T2]]
1043;
1044  %t1 = zext <2 x i32> %a to <2 x i64>
1045  %t2 = zext <2 x i1> %b to <2 x i64>
1046  %t3 = shl nuw <2 x i64> %t1, <i64 32, i64 32>
1047  %t4 = or <2 x i64> %t3, %t2
1048  %t5 = and <2 x i64> %t4, <i64 1, i64 1>
1049  ret <2 x i64> %t5
1050}
1051
1052define <2 x i64> @shl_or_and2v(<2 x i32> %a, <2 x i1> %b) {
1053; CHECK-LABEL: @shl_or_and2v(
1054; CHECK-NEXT:    [[T1:%.*]] = zext <2 x i1> [[B:%.*]] to <2 x i64>
1055; CHECK-NEXT:    [[T3:%.*]] = shl nuw <2 x i64> [[T1]], <i64 32, i64 32>
1056; CHECK-NEXT:    ret <2 x i64> [[T3]]
1057;
1058  %t1 = zext <2 x i1> %b to <2 x i64>
1059  %t2 = zext <2 x i32> %a to <2 x i64>
1060  %t3 = shl nuw <2 x i64> %t1, <i64 32, i64 32>
1061  %t4 = or <2 x i64> %t2, %t3
1062  %t5 = and <2 x i64> %t4, <i64 4294967296, i64 4294967296>
1063  ret <2 x i64> %t5
1064}
1065
1066; A variation of above test case, but fails due to the mask value
1067define <2 x i32> @shl_or_and3v(<2 x i16> %a, <2 x i16> %b) {
1068; CHECK-LABEL: @shl_or_and3v(
1069; CHECK-NEXT:    [[T1:%.*]] = zext <2 x i16> [[A:%.*]] to <2 x i32>
1070; CHECK-NEXT:    [[T2:%.*]] = zext <2 x i16> [[B:%.*]] to <2 x i32>
1071; CHECK-NEXT:    [[T3:%.*]] = shl nuw <2 x i32> [[T1]], <i32 16, i32 16>
1072; CHECK-NEXT:    [[T4:%.*]] = or <2 x i32> [[T2]], [[T3]]
1073; CHECK-NEXT:    [[T5:%.*]] = and <2 x i32> [[T4]], <i32 -65535, i32 -65535>
1074; CHECK-NEXT:    ret <2 x i32> [[T5]]
1075;
1076  %t1 = zext <2 x i16> %a to <2 x i32>
1077  %t2 = zext <2 x i16> %b to <2 x i32>
1078  %t3 = shl nuw <2 x i32> %t1, <i32 16, i32 16>
1079  %t4 = or <2 x i32> %t2, %t3
1080  %t5 = and <2 x i32> %t4, <i32 4294901761, i32 4294901761> ; mask with 0xFFFF0001
1081  ret <2 x i32> %t5
1082}
1083
1084define i8 @and_add_sub(i8 %x) {
1085; CHECK-LABEL: @and_add_sub(
1086; CHECK-NEXT:    ret i8 0
1087;
1088  %a = add i8 %x, -1
1089  %s = sub i8 0, %x
1090  %r = and i8 %a, %s
1091  ret i8 %r
1092}
1093
1094define <2 x i8> @and_sub_add(<2 x i8> %x) {
1095; CHECK-LABEL: @and_sub_add(
1096; CHECK-NEXT:    ret <2 x i8> zeroinitializer
1097;
1098  %a = add <2 x i8> %x, <i8 -4, i8 -4>
1099  %s = sub <2 x i8> <i8 3, i8 3>, %x
1100  %r = and <2 x i8> %s, %a
1101  ret <2 x i8> %r
1102}
1103
1104define i89 @or_add_sub(i89 %x) {
1105; CHECK-LABEL: @or_add_sub(
1106; CHECK-NEXT:    ret i89 -1
1107;
1108  %a = add i89 %x, 5
1109  %s = sub i89 -6, %x
1110  %r = or i89 %a, %s
1111  ret i89 %r
1112}
1113
1114define <3 x i8> @or_sub_add(<3 x i8> %x) {
1115; CHECK-LABEL: @or_sub_add(
1116; CHECK-NEXT:    ret <3 x i8> <i8 -1, i8 -1, i8 -1>
1117;
1118  %a = add <3 x i8> %x, <i8 42, i8 -12, i8 0>
1119  %s = sub <3 x i8> <i8 -43, i8 11, i8 -1>, %x
1120  %r = or <3 x i8> %s, %a
1121  ret <3 x i8> %r
1122}
1123
1124
1125define <2 x i17> @xor_add_sub(<2 x i17> %x) {
1126; CHECK-LABEL: @xor_add_sub(
1127; CHECK-NEXT:    ret <2 x i17> <i17 -1, i17 -1>
1128;
1129  %a = add <2 x i17> %x, <i17 3000, i17 23>
1130  %s = sub <2 x i17> <i17 -3001, i17 -24>, %x
1131  %r = xor <2 x i17> %a, %s
1132  ret <2 x i17> %r
1133}
1134
1135define i8 @xor_sub_add(i8 %x) {
1136; CHECK-LABEL: @xor_sub_add(
1137; CHECK-NEXT:    ret i8 -1
1138;
1139  %a = add i8 %x, 33
1140  %s = sub i8 -34, %x
1141  %r = xor i8 %s, %a
1142  ret i8 %r
1143}
1144
1145; Negative test
1146
1147define i8 @and_add_sub_wrong_const(i8 %x) {
1148; CHECK-LABEL: @and_add_sub_wrong_const(
1149; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], 6
1150; CHECK-NEXT:    [[S:%.*]] = sub i8 -6, [[X]]
1151; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], [[S]]
1152; CHECK-NEXT:    ret i8 [[R]]
1153;
1154  %a = add i8 %x, 6
1155  %s = sub i8 -6, %x
1156  %r = and i8 %a, %s
1157  ret i8 %r
1158}
1159
1160; Negative test
1161
1162define i8 @or_add_sub_wrong_var(i8 %x, i8 %y) {
1163; CHECK-LABEL: @or_add_sub_wrong_var(
1164; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], 5
1165; CHECK-NEXT:    [[S:%.*]] = sub i8 -6, [[Y:%.*]]
1166; CHECK-NEXT:    [[R:%.*]] = or i8 [[A]], [[S]]
1167; CHECK-NEXT:    ret i8 [[R]]
1168;
1169  %a = add i8 %x, 5
1170  %s = sub i8 -6, %y
1171  %r = or i8 %a, %s
1172  ret i8 %r
1173}
1174
1175; Negative test
1176
1177define i8 @xor_add_sub_wrong_op(i8 %x) {
1178; CHECK-LABEL: @xor_add_sub_wrong_op(
1179; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], 5
1180; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X]], -6
1181; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], [[S]]
1182; CHECK-NEXT:    ret i8 [[R]]
1183;
1184  %a = add i8 %x, 5
1185  %s = sub i8 %x, -6
1186  %r = xor i8 %a, %s
1187  ret i8 %r
1188}
1189
1190; `and` isn't needed if it doesn't actually change any bits.
1191define i8 @noop_and_t0(i8 %x) {
1192; CHECK-LABEL: @noop_and_t0(
1193; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 3
1194; CHECK-NEXT:    [[B:%.*]] = lshr i8 [[A]], 2
1195; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], 62
1196; CHECK-NEXT:    ret i8 [[R]]
1197;
1198  %a = shl i8 %x, 3
1199  %b = lshr i8 %a, 2
1200  %r = and i8 %b, 62
1201  ret i8 %r
1202}
1203define i8 @noop_and_t1(i8 %x) {
1204; CHECK-LABEL: @noop_and_t1(
1205; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 3
1206; CHECK-NEXT:    [[B:%.*]] = lshr i8 [[A]], 2
1207; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], 126
1208; CHECK-NEXT:    ret i8 [[R]]
1209;
1210  %a = shl i8 %x, 3
1211  %b = lshr i8 %a, 2
1212  %r = and i8 %b, 126
1213  ret i8 %r
1214}
1215