xref: /llvm-project/llvm/test/Transforms/InstCombine/xor.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4@G1 = global i32 0
5@G2 = global i32 0
6
7declare i32 @llvm.ctlz.i32(i32, i1)
8declare <2 x i8> @llvm.cttz.v2i8(<2 x i8>, i1)
9declare void @use(i8)
10
11define i1 @test0(i1 %A) {
12; CHECK-LABEL: @test0(
13; CHECK-NEXT:    ret i1 [[A:%.*]]
14;
15  %B = xor i1 %A, false
16  ret i1 %B
17}
18
19define i32 @test1(i32 %A) {
20; CHECK-LABEL: @test1(
21; CHECK-NEXT:    ret i32 [[A:%.*]]
22;
23  %B = xor i32 %A, 0
24  ret i32 %B
25}
26
27define i1 @test2(i1 %A) {
28; CHECK-LABEL: @test2(
29; CHECK-NEXT:    ret i1 false
30;
31  %B = xor i1 %A, %A
32  ret i1 %B
33}
34
35define i32 @test3(i32 %A) {
36; CHECK-LABEL: @test3(
37; CHECK-NEXT:    ret i32 0
38;
39  %B = xor i32 %A, %A
40  ret i32 %B
41}
42
43define i32 @test4(i32 %A) {
44; CHECK-LABEL: @test4(
45; CHECK-NEXT:    ret i32 -1
46;
47  %NotA = xor i32 -1, %A
48  %B = xor i32 %A, %NotA
49  ret i32 %B
50}
51
52define i32 @test5(i32 %A) {
53; CHECK-LABEL: @test5(
54; CHECK-NEXT:    [[R:%.*]] = and i32 [[A:%.*]], -124
55; CHECK-NEXT:    ret i32 [[R]]
56;
57  %t1 = or i32 %A, 123
58  %r = xor i32 %t1, 123
59  ret i32 %r
60}
61
62define i8 @test6(i8 %A) {
63; CHECK-LABEL: @test6(
64; CHECK-NEXT:    ret i8 [[A:%.*]]
65;
66  %B = xor i8 %A, 17
67  %C = xor i8 %B, 17
68  ret i8 %C
69}
70
71define i32 @test7(i32 %A, i32 %B) {
72; CHECK-LABEL: @test7(
73; CHECK-NEXT:    [[A1:%.*]] = and i32 [[A:%.*]], 7
74; CHECK-NEXT:    [[B1:%.*]] = and i32 [[B:%.*]], 128
75; CHECK-NEXT:    [[C1:%.*]] = or disjoint i32 [[A1]], [[B1]]
76; CHECK-NEXT:    ret i32 [[C1]]
77;
78  %A1 = and i32 %A, 7
79  %B1 = and i32 %B, 128
80  %C1 = xor i32 %A1, %B1
81  ret i32 %C1
82}
83
84define i8 @test8(i1 %c) {
85; CHECK-LABEL: @test8(
86; CHECK-NEXT:    br i1 [[C:%.*]], label [[FALSE:%.*]], label [[TRUE:%.*]]
87; CHECK:       True:
88; CHECK-NEXT:    ret i8 1
89; CHECK:       False:
90; CHECK-NEXT:    ret i8 3
91;
92  %d = xor i1 %c, true
93  br i1 %d, label %True, label %False
94
95True:
96  ret i8 1
97
98False:
99  ret i8 3
100}
101
102define i1 @test9(i8 %A) {
103; CHECK-LABEL: @test9(
104; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], 89
105; CHECK-NEXT:    ret i1 [[C]]
106;
107  %B = xor i8 %A, 123
108  %C = icmp eq i8 %B, 34
109  ret i1 %C
110}
111
112define <2 x i1> @test9vec(<2 x i8> %a) {
113; CHECK-LABEL: @test9vec(
114; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 89)
115; CHECK-NEXT:    ret <2 x i1> [[C]]
116;
117  %b = xor <2 x i8> %a, <i8 123, i8 123>
118  %c = icmp eq <2 x i8> %b, <i8 34, i8 34>
119  ret <2 x i1> %c
120}
121
122define i8 @test10(i8 %A) {
123; CHECK-LABEL: @test10(
124; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], 3
125; CHECK-NEXT:    [[C:%.*]] = or disjoint i8 [[B]], 4
126; CHECK-NEXT:    ret i8 [[C]]
127;
128  %B = and i8 %A, 3
129  %C = xor i8 %B, 4
130  ret i8 %C
131}
132
133define i8 @test11(i8 %A) {
134; CHECK-LABEL: @test11(
135; CHECK-NEXT:    [[B:%.*]] = and i8 [[A:%.*]], -13
136; CHECK-NEXT:    [[C:%.*]] = or disjoint i8 [[B]], 8
137; CHECK-NEXT:    ret i8 [[C]]
138;
139  %B = or i8 %A, 12
140  %C = xor i8 %B, 4
141  ret i8 %C
142}
143
144define i1 @test12(i8 %A) {
145; CHECK-LABEL: @test12(
146; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], 4
147; CHECK-NEXT:    ret i1 [[C]]
148;
149  %B = xor i8 %A, 4
150  %c = icmp ne i8 %B, 0
151  ret i1 %c
152}
153
154define <2 x i1> @test12vec(<2 x i8> %a) {
155; CHECK-LABEL: @test12vec(
156; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 4)
157; CHECK-NEXT:    ret <2 x i1> [[C]]
158;
159  %b = xor <2 x i8> %a, <i8 4, i8 4>
160  %c = icmp ne <2 x i8> %b, zeroinitializer
161  ret <2 x i1> %c
162}
163
164define i32 @test18(i32 %A) {
165; CHECK-LABEL: @test18(
166; CHECK-NEXT:    [[C:%.*]] = add i32 [[A:%.*]], 124
167; CHECK-NEXT:    ret i32 [[C]]
168;
169  %B = xor i32 %A, -1
170  %C = sub i32 123, %B
171  ret i32 %C
172}
173
174define i32 @test19(i32 %A, i32 %B) {
175; CHECK-LABEL: @test19(
176; CHECK-NEXT:    ret i32 [[B:%.*]]
177;
178  %C = xor i32 %A, %B
179  %D = xor i32 %C, %A
180  ret i32 %D
181}
182
183define void @test20(i32 %A, i32 %B) {
184; CHECK-LABEL: @test20(
185; CHECK-NEXT:    store i32 [[B:%.*]], ptr @G1, align 4
186; CHECK-NEXT:    store i32 [[A:%.*]], ptr @G2, align 4
187; CHECK-NEXT:    ret void
188;
189  %t2 = xor i32 %B, %A
190  %t5 = xor i32 %t2, %B
191  %t8 = xor i32 %t5, %t2
192  store i32 %t8, ptr @G1
193  store i32 %t5, ptr @G2
194  ret void
195}
196
197define i32 @test22(i1 %X) {
198; CHECK-LABEL: @test22(
199; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[X:%.*]] to i32
200; CHECK-NEXT:    ret i32 [[Z]]
201;
202  %Y = xor i1 %X, true
203  %Z = zext i1 %Y to i32
204  %Q = xor i32 %Z, 1
205  ret i32 %Q
206}
207
208; Look through a zext between xors.
209
210define i32 @fold_zext_xor_sandwich(i1 %X) {
211; CHECK-LABEL: @fold_zext_xor_sandwich(
212; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[X:%.*]] to i32
213; CHECK-NEXT:    [[Q:%.*]] = xor i32 [[Z]], 3
214; CHECK-NEXT:    ret i32 [[Q]]
215;
216  %Y = xor i1 %X, true
217  %Z = zext i1 %Y to i32
218  %Q = xor i32 %Z, 2
219  ret i32 %Q
220}
221
222define <2 x i32> @fold_zext_xor_sandwich_vec(<2 x i1> %X) {
223; CHECK-LABEL: @fold_zext_xor_sandwich_vec(
224; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i1> [[X:%.*]] to <2 x i32>
225; CHECK-NEXT:    [[Q:%.*]] = xor <2 x i32> [[Z]], splat (i32 3)
226; CHECK-NEXT:    ret <2 x i32> [[Q]]
227;
228  %Y = xor <2 x i1> %X, <i1 true, i1 true>
229  %Z = zext <2 x i1> %Y to <2 x i32>
230  %Q = xor <2 x i32> %Z, <i32 2, i32 2>
231  ret <2 x i32> %Q
232}
233
234define i1 @test23(i32 %a, i32 %b) {
235; CHECK-LABEL: @test23(
236; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[B:%.*]], 0
237; CHECK-NEXT:    ret i1 [[T4]]
238;
239  %t2 = xor i32 %b, %a
240  %t4 = icmp eq i32 %t2, %a
241  ret i1 %t4
242}
243
244define i1 @test24(i32 %c, i32 %d) {
245; CHECK-LABEL: @test24(
246; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[D:%.*]], 0
247; CHECK-NEXT:    ret i1 [[T4]]
248;
249  %t2 = xor i32 %d, %c
250  %t4 = icmp ne i32 %t2, %c
251  ret i1 %t4
252}
253
254define i32 @test25(i32 %g, i32 %h) {
255; CHECK-LABEL: @test25(
256; CHECK-NEXT:    [[T4:%.*]] = and i32 [[G:%.*]], [[H:%.*]]
257; CHECK-NEXT:    ret i32 [[T4]]
258;
259  %h2 = xor i32 %h, -1
260  %t2 = and i32 %h2, %g
261  %t4 = xor i32 %t2, %g
262  ret i32 %t4
263}
264
265define i32 @test27(i32 %b, i32 %c, i32 %d) {
266; CHECK-LABEL: @test27(
267; CHECK-NEXT:    [[T6:%.*]] = icmp eq i32 [[B:%.*]], [[C:%.*]]
268; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32
269; CHECK-NEXT:    ret i32 [[T7]]
270;
271  %t2 = xor i32 %d, %b
272  %t5 = xor i32 %d, %c
273  %t6 = icmp eq i32 %t2, %t5
274  %t7 = zext i1 %t6 to i32
275  ret i32 %t7
276}
277
278define i32 @test28(i32 %indvar) {
279; CHECK-LABEL: @test28(
280; CHECK-NEXT:    [[T214:%.*]] = add i32 [[INDVAR:%.*]], 1
281; CHECK-NEXT:    ret i32 [[T214]]
282;
283  %t7 = add i32 %indvar, -2147483647
284  %t214 = xor i32 %t7, -2147483648
285  ret i32 %t214
286}
287
288define <2 x i32> @test28vec(<2 x i32> %indvar) {
289; CHECK-LABEL: @test28vec(
290; CHECK-NEXT:    [[T214:%.*]] = add <2 x i32> [[INDVAR:%.*]], splat (i32 1)
291; CHECK-NEXT:    ret <2 x i32> [[T214]]
292;
293  %t7 = add <2 x i32> %indvar, <i32 -2147483647, i32 -2147483647>
294  %t214 = xor <2 x i32> %t7, <i32 -2147483648, i32 -2147483648>
295  ret <2 x i32> %t214
296}
297
298define i32 @test28_sub(i32 %indvar) {
299; CHECK-LABEL: @test28_sub(
300; CHECK-NEXT:    [[T214:%.*]] = sub i32 1, [[INDVAR:%.*]]
301; CHECK-NEXT:    ret i32 [[T214]]
302;
303  %t7 = sub i32 -2147483647, %indvar
304  %t214 = xor i32 %t7, -2147483648
305  ret i32 %t214
306}
307
308define <2 x i32> @test28_subvec(<2 x i32> %indvar) {
309; CHECK-LABEL: @test28_subvec(
310; CHECK-NEXT:    [[T214:%.*]] = sub <2 x i32> splat (i32 1), [[INDVAR:%.*]]
311; CHECK-NEXT:    ret <2 x i32> [[T214]]
312;
313  %t7 = sub <2 x i32> <i32 -2147483647, i32 -2147483647>, %indvar
314  %t214 = xor <2 x i32> %t7, <i32 -2147483648, i32 -2147483648>
315  ret <2 x i32> %t214
316}
317
318define i32 @test29(i1 %C) {
319; CHECK-LABEL: @test29(
320; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 915, i32 113
321; CHECK-NEXT:    ret i32 [[V]]
322;
323  %A = select i1 %C, i32 1000, i32 10
324  %V = xor i32 %A, 123
325  ret i32 %V
326}
327
328define <2 x i32> @test29vec(i1 %C) {
329; CHECK-LABEL: @test29vec(
330; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 915), <2 x i32> splat (i32 113)
331; CHECK-NEXT:    ret <2 x i32> [[V]]
332;
333  %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
334  %V = xor <2 x i32> %A, <i32 123, i32 123>
335  ret <2 x i32> %V
336}
337
338define <2 x i32> @test29vec2(i1 %C) {
339; CHECK-LABEL: @test29vec2(
340; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 915, i32 2185>, <2 x i32> <i32 113, i32 339>
341; CHECK-NEXT:    ret <2 x i32> [[V]]
342;
343  %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
344  %V = xor <2 x i32> %A, <i32 123, i32 333>
345  ret <2 x i32> %V
346}
347
348define i32 @test30(i1 %which) {
349; CHECK-LABEL: @test30(
350; CHECK-NEXT:  entry:
351; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
352; CHECK:       delay:
353; CHECK-NEXT:    br label [[FINAL]]
354; CHECK:       final:
355; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 915, [[ENTRY:%.*]] ], [ 113, [[DELAY]] ]
356; CHECK-NEXT:    ret i32 [[A]]
357;
358entry:
359  br i1 %which, label %final, label %delay
360
361delay:
362  br label %final
363
364final:
365  %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
366  %value = xor i32 %A, 123
367  ret i32 %value
368}
369
370define <2 x i32> @test30vec(i1 %which) {
371; CHECK-LABEL: @test30vec(
372; CHECK-NEXT:  entry:
373; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
374; CHECK:       delay:
375; CHECK-NEXT:    br label [[FINAL]]
376; CHECK:       final:
377; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ splat (i32 915), [[ENTRY:%.*]] ], [ splat (i32 113), [[DELAY]] ]
378; CHECK-NEXT:    ret <2 x i32> [[A]]
379;
380entry:
381  br i1 %which, label %final, label %delay
382
383delay:
384  br label %final
385
386final:
387  %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
388  %value = xor <2 x i32> %A, <i32 123, i32 123>
389  ret <2 x i32> %value
390}
391
392define <2 x i32> @test30vec2(i1 %which) {
393; CHECK-LABEL: @test30vec2(
394; CHECK-NEXT:  entry:
395; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
396; CHECK:       delay:
397; CHECK-NEXT:    br label [[FINAL]]
398; CHECK:       final:
399; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 915, i32 2185>, [[ENTRY:%.*]] ], [ <i32 113, i32 339>, [[DELAY]] ]
400; CHECK-NEXT:    ret <2 x i32> [[A]]
401;
402entry:
403  br i1 %which, label %final, label %delay
404
405delay:
406  br label %final
407
408final:
409  %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
410  %value = xor <2 x i32> %A, <i32 123, i32 333>
411  ret <2 x i32> %value
412}
413
414; B ^ (B | A) --> A & ~B
415; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
416
417define i32 @or_xor_commute1(i32 %p1, i32 %p2) {
418; CHECK-LABEL: @or_xor_commute1(
419; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
420; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
421; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
422; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
423; CHECK-NEXT:    ret i32 [[R]]
424;
425  %a = udiv i32 42, %p1
426  %b = udiv i32 42, %p2
427  %o = or i32 %b, %a
428  %r = xor i32 %b, %o
429  ret i32 %r
430}
431
432; B ^ (B | A) --> A & ~B
433; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
434
435define i32 @or_xor_commute2(i32 %p1, i32 %p2) {
436; CHECK-LABEL: @or_xor_commute2(
437; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
438; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
439; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
440; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
441; CHECK-NEXT:    ret i32 [[R]]
442;
443  %a = udiv i32 42, %p1
444  %b = udiv i32 42, %p2
445  %o = or i32 %a, %b
446  %r = xor i32 %o, %b
447  ret i32 %r
448}
449
450; B ^ (B | A) --> A & ~B
451; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
452
453define i32 @or_xor_commute3(i32 %p1, i32 %p2) {
454; CHECK-LABEL: @or_xor_commute3(
455; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
456; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
457; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
458; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
459; CHECK-NEXT:    ret i32 [[R]]
460;
461  %a = udiv i32 42, %p1
462  %b = udiv i32 42, %p2
463  %o = or i32 %b, %a
464  %r = xor i32 %o, %b
465  ret i32 %r
466}
467
468; B ^ (B | A) --> A & ~B
469; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
470
471define i32 @or_xor_commute4(i32 %p1, i32 %p2) {
472; CHECK-LABEL: @or_xor_commute4(
473; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
474; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
475; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
476; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
477; CHECK-NEXT:    ret i32 [[R]]
478;
479  %a = udiv i32 42, %p1
480  %b = udiv i32 42, %p2
481  %o = or i32 %a, %b
482  %r = xor i32 %b, %o
483  ret i32 %r
484}
485
486define i32 @or_xor_extra_use(i32 %a, i32 %b, ptr %p) {
487; CHECK-LABEL: @or_xor_extra_use(
488; CHECK-NEXT:    [[O:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
489; CHECK-NEXT:    store i32 [[O]], ptr [[P:%.*]], align 4
490; CHECK-NEXT:    [[R:%.*]] = xor i32 [[B]], [[O]]
491; CHECK-NEXT:    ret i32 [[R]]
492;
493  %o = or i32 %a, %b
494  store i32 %o, ptr %p
495  %r = xor i32 %b, %o
496  ret i32 %r
497}
498
499; B ^ (B & A) --> ~A & B
500; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
501
502define i32 @and_xor_commute1(i32 %p1, i32 %p2) {
503; CHECK-LABEL: @and_xor_commute1(
504; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
505; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
506; CHECK-NEXT:    [[O1:%.*]] = xor i32 [[A]], -1
507; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[O1]]
508; CHECK-NEXT:    ret i32 [[R]]
509;
510  %a = udiv i32 42, %p1
511  %b = udiv i32 42, %p2
512  %o = and i32 %b, %a
513  %r = xor i32 %b, %o
514  ret i32 %r
515}
516
517; B ^ (B & A) --> ~A & B
518; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
519
520define i32 @and_xor_commute2(i32 %p1, i32 %p2) {
521; CHECK-LABEL: @and_xor_commute2(
522; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
523; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
524; CHECK-NEXT:    [[O1:%.*]] = xor i32 [[A]], -1
525; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[O1]]
526; CHECK-NEXT:    ret i32 [[R]]
527;
528  %a = udiv i32 42, %p1
529  %b = udiv i32 42, %p2
530  %o = and i32 %a, %b
531  %r = xor i32 %o, %b
532  ret i32 %r
533}
534
535; B ^ (B & A) --> ~A & B
536; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
537
538define i32 @and_xor_commute3(i32 %p1, i32 %p2) {
539; CHECK-LABEL: @and_xor_commute3(
540; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
541; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
542; CHECK-NEXT:    [[B1:%.*]] = xor i32 [[A]], -1
543; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[B1]]
544; CHECK-NEXT:    ret i32 [[R]]
545;
546  %a = udiv i32 42, %p1
547  %b = udiv i32 42, %p2
548  %o = and i32 %b, %a
549  %r = xor i32 %o, %b
550  ret i32 %r
551}
552
553; B ^ (B & A) --> ~A & B
554; The division ops are here to thwart complexity-based canonicalization: all ops are binops.
555
556define i32 @and_xor_commute4(i32 %p1, i32 %p2) {
557; CHECK-LABEL: @and_xor_commute4(
558; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[P1:%.*]]
559; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[P2:%.*]]
560; CHECK-NEXT:    [[O1:%.*]] = xor i32 [[A]], -1
561; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[O1]]
562; CHECK-NEXT:    ret i32 [[R]]
563;
564  %a = udiv i32 42, %p1
565  %b = udiv i32 42, %p2
566  %o = and i32 %a, %b
567  %r = xor i32 %b, %o
568  ret i32 %r
569}
570
571define i32 @and_xor_extra_use(i32 %a, i32 %b, ptr %p) {
572; CHECK-LABEL: @and_xor_extra_use(
573; CHECK-NEXT:    [[O:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
574; CHECK-NEXT:    store i32 [[O]], ptr [[P:%.*]], align 4
575; CHECK-NEXT:    [[R:%.*]] = xor i32 [[B]], [[O]]
576; CHECK-NEXT:    ret i32 [[R]]
577;
578  %o = and i32 %a, %b
579  store i32 %o, ptr %p
580  %r = xor i32 %b, %o
581  ret i32 %r
582}
583
584; (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1
585; The extra use (store) is here because the simpler case
586; may be transformed using demanded bits.
587
588define i8 @xor_or_not(i8 %x, ptr %p) {
589; CHECK-LABEL: @xor_or_not(
590; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
591; CHECK-NEXT:    store i8 [[NX]], ptr [[P:%.*]], align 1
592; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -8
593; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -13
594; CHECK-NEXT:    ret i8 [[R]]
595;
596  %nx = xor i8 %x, -1
597  store i8 %nx, ptr %p
598  %or = or i8 %nx, 7
599  %r = xor i8 %or, 12
600  ret i8 %r
601}
602
603; Don't do this if the 'or' has extra uses.
604
605define i8 @xor_or_not_uses(i8 %x, ptr %p) {
606; CHECK-LABEL: @xor_or_not_uses(
607; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
608; CHECK-NEXT:    [[OR:%.*]] = or i8 [[NX]], 7
609; CHECK-NEXT:    store i8 [[OR]], ptr [[P:%.*]], align 1
610; CHECK-NEXT:    [[R:%.*]] = xor i8 [[OR]], 12
611; CHECK-NEXT:    ret i8 [[R]]
612;
613  %nx = xor i8 %x, -1
614  %or = or i8 %nx, 7
615  store i8 %or, ptr %p
616  %r = xor i8 %or, 12
617  ret i8 %r
618}
619
620; (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1
621; The extra use (store) is here because the simpler case
622; may be transformed using demanded bits.
623
624define i8 @xor_and_not(i8 %x, ptr %p) {
625; CHECK-LABEL: @xor_and_not(
626; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
627; CHECK-NEXT:    store i8 [[NX]], ptr [[P:%.*]], align 1
628; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], 42
629; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], 53
630; CHECK-NEXT:    ret i8 [[R]]
631;
632  %nx = xor i8 %x, -1
633  store i8 %nx, ptr %p
634  %and = and i8 %nx, 42
635  %r = xor i8 %and, 31
636  ret i8 %r
637}
638
639; Don't do this if the 'and' has extra uses.
640
641define i8 @xor_and_not_uses(i8 %x, ptr %p) {
642; CHECK-LABEL: @xor_and_not_uses(
643; CHECK-NEXT:    [[NX:%.*]] = and i8 [[X:%.*]], 42
644; CHECK-NEXT:    [[AND:%.*]] = xor i8 [[NX]], 42
645; CHECK-NEXT:    store i8 [[AND]], ptr [[P:%.*]], align 1
646; CHECK-NEXT:    [[R:%.*]] = xor i8 [[NX]], 53
647; CHECK-NEXT:    ret i8 [[R]]
648;
649  %nx = xor i8 %x, -1
650  %and = and i8 %nx, 42
651  store i8 %and, ptr %p
652  %r = xor i8 %and, 31
653  ret i8 %r
654}
655
656; The tests 39-47 are related to the canonicalization:
657; %notx = xor i32 %x, -1
658; %cmp = icmp sgt i32 %notx, %y
659; %smax = select i1 %cmp, i32 %notx, i32 %y
660; %res = xor i32 %smax, -1
661;   =>
662; %noty = xor i32 %y, -1
663; %cmp2 = icmp slt %x, %noty
664; %res = select i1 %cmp2, i32 %x, i32 %noty
665;
666; Same transformations is valid for smin/umax/umin.
667
668define i32 @test39(i32 %x) {
669; CHECK-LABEL: @test39(
670; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
671; CHECK-NEXT:    ret i32 [[TMP1]]
672;
673  %1 = xor i32 %x, -1
674  %2 = icmp sgt i32 %1, -256
675  %3 = select i1 %2, i32 %1, i32 -256
676  %res = xor i32 %3, -1
677  ret i32 %res
678}
679
680define i32 @test40(i32 %x, i32 %y) {
681; CHECK-LABEL: @test40(
682; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
683; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[TMP1]])
684; CHECK-NEXT:    ret i32 [[RES]]
685;
686  %notx = xor i32 %x, -1
687  %cmp1 = icmp sgt i32 %notx, %y
688  %smax = select i1 %cmp1, i32 %notx, i32 %y
689  %res = xor i32 %smax, -1
690  ret i32 %res
691}
692
693define i32 @test41(i32 %x, i32 %y) {
694; CHECK-LABEL: @test41(
695; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
696; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[TMP1]])
697; CHECK-NEXT:    ret i32 [[RES]]
698;
699  %notx = xor i32 %x, -1
700  %cmp1 = icmp slt i32 %notx, %y
701  %smin = select i1 %cmp1, i32 %notx, i32 %y
702  %res = xor i32 %smin, -1
703  ret i32 %res
704}
705
706define i32 @test42(i32 %x, i32 %y) {
707; CHECK-LABEL: @test42(
708; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
709; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[TMP1]])
710; CHECK-NEXT:    ret i32 [[RES]]
711;
712  %notx = xor i32 %x, -1
713  %cmp1 = icmp ugt i32 %notx, %y
714  %umax = select i1 %cmp1, i32 %notx, i32 %y
715  %res = xor i32 %umax, -1
716  ret i32 %res
717}
718
719define i32 @test43(i32 %x, i32 %y) {
720; CHECK-LABEL: @test43(
721; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
722; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[TMP1]])
723; CHECK-NEXT:    ret i32 [[RES]]
724;
725  %notx = xor i32 %x, -1
726  %cmp1 = icmp ult i32 %notx, %y
727  %umin = select i1 %cmp1, i32 %notx, i32 %y
728  %res = xor i32 %umin, -1
729  ret i32 %res
730}
731
732define i32 @test44(i32 %x, i32 %y) {
733; CHECK-LABEL: @test44(
734; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 -4, [[Y:%.*]]
735; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[TMP1]])
736; CHECK-NEXT:    ret i32 [[TMP2]]
737;
738  %z = add i32 %y, 3 ; thwart complexity-based canonicalization
739  %notx = xor i32 %x, -1
740  %cmp1 = icmp ult i32 %z, %notx
741  %umin = select i1 %cmp1, i32 %z, i32 %notx
742  %res = xor i32 %umin, -1
743  ret i32 %res
744}
745
746define i32 @test45(i32 %x, i32 %y) {
747; CHECK-LABEL: @test45(
748; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X:%.*]])
749; CHECK-NEXT:    ret i32 [[TMP1]]
750;
751  %z = xor i32 %y, -1
752  %notx = xor i32 %x, -1
753  %cmp1 = icmp ult i32 %z, %notx
754  %umin = select i1 %cmp1, i32 %z, i32 %notx
755  %res = xor i32 %umin, -1
756  ret i32 %res
757}
758
759; Check that we work with splat vectors also.
760define <4 x i32> @test46(<4 x i32> %x) {
761; CHECK-LABEL: @test46(
762; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[X:%.*]], <4 x i32> splat (i32 255))
763; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
764;
765  %1 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
766  %2 = icmp sgt <4 x i32> %1, <i32 -256, i32 -256, i32 -256, i32 -256>
767  %3 = select <4 x i1> %2, <4 x i32> %1, <4 x i32> <i32 -256, i32 -256, i32 -256, i32 -256>
768  %4 = xor <4 x i32> %3, <i32 -1, i32 -1, i32 -1, i32 -1>
769  ret <4 x i32> %4
770}
771
772; Test case when select pattern has more than one use.
773define i32 @test47(i32 %x, i32 %y, i32 %z) {
774; CHECK-LABEL: @test47(
775; CHECK-NEXT:    [[NOTX:%.*]] = xor i32 [[X:%.*]], -1
776; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[NOTX]])
777; CHECK-NEXT:    [[UMIN:%.*]] = xor i32 [[UMAX]], -1
778; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[UMAX]], [[Z:%.*]]
779; CHECK-NEXT:    [[RES:%.*]] = mul i32 [[ADD]], [[UMIN]]
780; CHECK-NEXT:    ret i32 [[RES]]
781;
782  %notx = xor i32 %x, -1
783  %cmp1 = icmp ugt i32 %notx, %y
784  %umax = select i1 %cmp1, i32 %notx, i32 %y
785  %umin = xor i32 %umax, -1
786  %add = add i32 %umax, %z
787  %res = mul i32 %umin, %add
788  ret i32 %res
789}
790
791define i32 @test48(i32 %x) {
792; CHECK-LABEL: @test48(
793; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
794; CHECK-NEXT:    [[D:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 -1)
795; CHECK-NEXT:    ret i32 [[D]]
796;
797  %a = sub i32 -2, %x
798  %b = icmp sgt i32 %a, 0
799  %c = select i1 %b, i32 %a, i32 0
800  %d = xor i32 %c, -1
801  ret i32 %d
802}
803
804define <2 x i32> @test48vec(<2 x i32> %x) {
805; CHECK-LABEL: @test48vec(
806; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 1)
807; CHECK-NEXT:    [[D:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[TMP1]], <2 x i32> splat (i32 -1))
808; CHECK-NEXT:    ret <2 x i32> [[D]]
809;
810  %a = sub <2 x i32> <i32 -2, i32 -2>, %x
811  %b = icmp sgt <2 x i32> %a, zeroinitializer
812  %c = select <2 x i1> %b, <2 x i32> %a, <2 x i32> zeroinitializer
813  %d = xor <2 x i32> %c, <i32 -1, i32 -1>
814  ret <2 x i32> %d
815}
816
817define i32 @test49(i32 %x) {
818; CHECK-LABEL: @test49(
819; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 1, [[X:%.*]]
820; CHECK-NEXT:    [[D:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0)
821; CHECK-NEXT:    ret i32 [[D]]
822;
823  %a = add i32 %x, -2
824  %b = icmp slt i32 %a, -1
825  %c = select i1 %b, i32 %a, i32 -1
826  %d = xor i32 %c, -1
827  ret i32 %d
828}
829
830define <2 x i32> @test49vec(<2 x i32> %x) {
831; CHECK-LABEL: @test49vec(
832; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> splat (i32 1), [[X:%.*]]
833; CHECK-NEXT:    [[D:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[TMP1]], <2 x i32> zeroinitializer)
834; CHECK-NEXT:    ret <2 x i32> [[D]]
835;
836  %a = add <2 x i32> %x, <i32 -2, i32 -2>
837  %b = icmp slt <2 x i32> %a, <i32 -1, i32 -1>
838  %c = select <2 x i1> %b, <2 x i32> %a, <2 x i32> <i32 -1, i32 -1>
839  %d = xor <2 x i32> %c, <i32 -1, i32 -1>
840  ret <2 x i32> %d
841}
842
843define i32 @test50(i32 %x, i32 %y) {
844; CHECK-LABEL: @test50(
845; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 1, [[X:%.*]]
846; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[Y:%.*]], 1
847; CHECK-NEXT:    [[E:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 [[TMP2]])
848; CHECK-NEXT:    ret i32 [[E]]
849;
850  %a = add i32 %x, -2
851  %b = sub i32 -2, %y
852  %c = icmp slt i32 %a, %b
853  %d = select i1 %c, i32 %a, i32 %b
854  %e = xor i32 %d, -1
855  ret i32 %e
856}
857
858define <2 x i32> @test50vec(<2 x i32> %x, <2 x i32> %y) {
859; CHECK-LABEL: @test50vec(
860; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> splat (i32 1), [[X:%.*]]
861; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 1)
862; CHECK-NEXT:    [[E:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[TMP2]])
863; CHECK-NEXT:    ret <2 x i32> [[E]]
864;
865  %a = add <2 x i32> %x, <i32 -2, i32 -2>
866  %b = sub <2 x i32> <i32 -2, i32 -2>, %y
867  %c = icmp slt <2 x i32> %a, %b
868  %d = select <2 x i1> %c, <2 x i32> %a, <2 x i32> %b
869  %e = xor <2 x i32> %d, <i32 -1, i32 -1>
870  ret <2 x i32> %e
871}
872
873define i32 @test51(i32 %x, i32 %y) {
874; CHECK-LABEL: @test51(
875; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 -3, [[X:%.*]]
876; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[Y:%.*]], -3
877; CHECK-NEXT:    [[E:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 [[TMP2]])
878; CHECK-NEXT:    ret i32 [[E]]
879;
880  %a = add i32 %x, 2
881  %b = sub i32 2, %y
882  %c = icmp sgt i32 %a, %b
883  %d = select i1 %c, i32 %a, i32 %b
884  %e = xor i32 %d, -1
885  ret i32 %e
886}
887
888define <2 x i32> @test51vec(<2 x i32> %x, <2 x i32> %y) {
889; CHECK-LABEL: @test51vec(
890; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i32> splat (i32 -3), [[X:%.*]]
891; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 -3)
892; CHECK-NEXT:    [[E:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[TMP2]])
893; CHECK-NEXT:    ret <2 x i32> [[E]]
894;
895  %a = add <2 x i32> %x, <i32 2, i32 2>
896  %b = sub <2 x i32> <i32 2, i32 2>, %y
897  %c = icmp sgt <2 x i32> %a, %b
898  %d = select <2 x i1> %c, <2 x i32> %a, <2 x i32> %b
899  %e = xor <2 x i32> %d, <i32 -1, i32 -1>
900  ret <2 x i32> %e
901}
902
903define i4 @or_or_xor(i4 %x, i4 %y, i4 %z) {
904; CHECK-LABEL: @or_or_xor(
905; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Z:%.*]], -1
906; CHECK-NEXT:    [[TMP2:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
907; CHECK-NEXT:    [[R:%.*]] = and i4 [[TMP2]], [[TMP1]]
908; CHECK-NEXT:    ret i4 [[R]]
909;
910  %o1 = or i4 %z, %x
911  %o2 = or i4 %z, %y
912  %r = xor i4 %o1, %o2
913  ret i4 %r
914}
915
916define i4 @or_or_xor_commute1(i4 %x, i4 %y, i4 %z) {
917; CHECK-LABEL: @or_or_xor_commute1(
918; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Z:%.*]], -1
919; CHECK-NEXT:    [[TMP2:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
920; CHECK-NEXT:    [[R:%.*]] = and i4 [[TMP2]], [[TMP1]]
921; CHECK-NEXT:    ret i4 [[R]]
922;
923  %o1 = or i4 %x, %z
924  %o2 = or i4 %z, %y
925  %r = xor i4 %o1, %o2
926  ret i4 %r
927}
928
929define i4 @or_or_xor_commute2(i4 %x, i4 %y, i4 %z) {
930; CHECK-LABEL: @or_or_xor_commute2(
931; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Z:%.*]], -1
932; CHECK-NEXT:    [[TMP2:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
933; CHECK-NEXT:    [[R:%.*]] = and i4 [[TMP2]], [[TMP1]]
934; CHECK-NEXT:    ret i4 [[R]]
935;
936  %o1 = or i4 %z, %x
937  %o2 = or i4 %y, %z
938  %r = xor i4 %o1, %o2
939  ret i4 %r
940}
941
942define <2 x i4> @or_or_xor_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
943; CHECK-LABEL: @or_or_xor_commute3(
944; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[Z:%.*]], splat (i4 -1)
945; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
946; CHECK-NEXT:    [[R:%.*]] = and <2 x i4> [[TMP2]], [[TMP1]]
947; CHECK-NEXT:    ret <2 x i4> [[R]]
948;
949  %o1 = or <2 x i4> %x, %z
950  %o2 = or <2 x i4> %y, %z
951  %r = xor <2 x i4> %o1, %o2
952  ret <2 x i4> %r
953}
954
955define i4 @or_or_xor_use1(i4 %x, i4 %y, i4 %z, ptr %p) {
956; CHECK-LABEL: @or_or_xor_use1(
957; CHECK-NEXT:    [[O1:%.*]] = or i4 [[Z:%.*]], [[X:%.*]]
958; CHECK-NEXT:    store i4 [[O1]], ptr [[P:%.*]], align 1
959; CHECK-NEXT:    [[O2:%.*]] = or i4 [[Z]], [[Y:%.*]]
960; CHECK-NEXT:    [[R:%.*]] = xor i4 [[O1]], [[O2]]
961; CHECK-NEXT:    ret i4 [[R]]
962;
963  %o1 = or i4 %z, %x
964  store i4 %o1, ptr %p
965  %o2 = or i4 %z, %y
966  %r = xor i4 %o1, %o2
967  ret i4 %r
968}
969
970define i4 @or_or_xor_use2(i4 %x, i4 %y, i4 %z, ptr %p) {
971; CHECK-LABEL: @or_or_xor_use2(
972; CHECK-NEXT:    [[O1:%.*]] = or i4 [[Z:%.*]], [[X:%.*]]
973; CHECK-NEXT:    [[O2:%.*]] = or i4 [[Z]], [[Y:%.*]]
974; CHECK-NEXT:    store i4 [[O2]], ptr [[P:%.*]], align 1
975; CHECK-NEXT:    [[R:%.*]] = xor i4 [[O1]], [[O2]]
976; CHECK-NEXT:    ret i4 [[R]]
977;
978  %o1 = or i4 %z, %x
979  %o2 = or i4 %z, %y
980  store i4 %o2, ptr %p
981  %r = xor i4 %o1, %o2
982  ret i4 %r
983}
984
985; PR32706 - https://bugs.llvm.org/show_bug.cgi?id=32706
986; Pin an xor constant operand to -1 if possible because 'not' is better for SCEV and codegen.
987
988define i32 @not_is_canonical(i32 %x, i32 %y) {
989; CHECK-LABEL: @not_is_canonical(
990; CHECK-NEXT:    [[SUB:%.*]] = xor i32 [[X:%.*]], -1
991; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[Y:%.*]], [[SUB]]
992; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[ADD]], 2
993; CHECK-NEXT:    ret i32 [[MUL]]
994;
995  %sub = xor i32 %x, 1073741823
996  %add = add i32 %sub, %y
997  %mul = shl i32 %add, 2
998  ret i32 %mul
999}
1000
1001define i8 @not_shl(i8 %x) {
1002; CHECK-LABEL: @not_shl(
1003; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X:%.*]], -1
1004; CHECK-NEXT:    [[R:%.*]] = shl i8 [[TMP1]], 7
1005; CHECK-NEXT:    ret i8 [[R]]
1006;
1007  %a = shl i8 %x, 7
1008  %r = xor i8 %a, 128
1009  ret i8 %r
1010}
1011
1012define <2 x i8> @not_shl_vec(<2 x i8> %x) {
1013; CHECK-LABEL: @not_shl_vec(
1014; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], splat (i8 -1)
1015; CHECK-NEXT:    [[R:%.*]] = shl <2 x i8> [[TMP1]], splat (i8 5)
1016; CHECK-NEXT:    ret <2 x i8> [[R]]
1017;
1018  %a = shl <2 x i8> %x, <i8 5, i8 5>
1019  %r = xor <2 x i8> %a, <i8 224, i8 224>
1020  ret <2 x i8> %r
1021}
1022
1023; negative test
1024
1025define i8 @not_shl_extra_use(i8 %x) {
1026; CHECK-LABEL: @not_shl_extra_use(
1027; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 7
1028; CHECK-NEXT:    call void @use(i8 [[A]])
1029; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], -128
1030; CHECK-NEXT:    ret i8 [[R]]
1031;
1032  %a = shl i8 %x, 7
1033  call void @use(i8 %a)
1034  %r = xor i8 %a, 128
1035  ret i8 %r
1036}
1037
1038; negative test
1039
1040define i8 @not_shl_wrong_const(i8 %x) {
1041; CHECK-LABEL: @not_shl_wrong_const(
1042; CHECK-NEXT:    [[A:%.*]] = shl i8 [[X:%.*]], 6
1043; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], -128
1044; CHECK-NEXT:    ret i8 [[R]]
1045;
1046  %a = shl i8 %x, 6
1047  %r = xor i8 %a, 128
1048  ret i8 %r
1049}
1050
1051define i8 @not_lshr(i8 %x) {
1052; CHECK-LABEL: @not_lshr(
1053; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X:%.*]], -1
1054; CHECK-NEXT:    [[R:%.*]] = lshr i8 [[TMP1]], 5
1055; CHECK-NEXT:    ret i8 [[R]]
1056;
1057  %a = lshr i8 %x, 5
1058  %r = xor i8 %a, 7
1059  ret i8 %r
1060}
1061
1062define <2 x i8> @not_lshr_vec(<2 x i8> %x) {
1063; CHECK-LABEL: @not_lshr_vec(
1064; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)
1065; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i8>
1066; CHECK-NEXT:    ret <2 x i8> [[R]]
1067;
1068  %a = lshr <2 x i8> %x, <i8 7, i8 7>
1069  %r = xor <2 x i8> %a, <i8 1, i8 1>
1070  ret <2 x i8> %r
1071}
1072
1073; negative test
1074
1075define i8 @not_lshr_extra_use(i8 %x) {
1076; CHECK-LABEL: @not_lshr_extra_use(
1077; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 5
1078; CHECK-NEXT:    call void @use(i8 [[A]])
1079; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 7
1080; CHECK-NEXT:    ret i8 [[R]]
1081;
1082  %a = lshr i8 %x, 5
1083  call void @use(i8 %a)
1084  %r = xor i8 %a, 7
1085  ret i8 %r
1086}
1087
1088; negative test
1089
1090define i8 @not_lshr_wrong_const(i8 %x) {
1091; CHECK-LABEL: @not_lshr_wrong_const(
1092; CHECK-NEXT:    [[A:%.*]] = lshr i8 [[X:%.*]], 5
1093; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 3
1094; CHECK-NEXT:    ret i8 [[R]]
1095;
1096  %a = lshr i8 %x, 5
1097  %r = xor i8 %a, 3
1098  ret i8 %r
1099}
1100
1101define i8 @ashr_not(i8 %x) {
1102; CHECK-LABEL: @ashr_not(
1103; CHECK-NEXT:    [[N:%.*]] = ashr i8 [[X:%.*]], 5
1104; CHECK-NEXT:    [[R:%.*]] = xor i8 [[N]], -1
1105; CHECK-NEXT:    ret i8 [[R]]
1106;
1107  %n = xor i8 %x, -1
1108  %r = ashr i8 %n, 5
1109  ret i8 %r
1110}
1111
1112; Unlike the logicial shifts, 'not' is canonicalized after ashr.
1113
1114define i8 @not_ashr(i8 %x) {
1115; CHECK-LABEL: @not_ashr(
1116; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 5
1117; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], -1
1118; CHECK-NEXT:    ret i8 [[R]]
1119;
1120  %a = ashr i8 %x, 5
1121  %r = xor i8 %a, -1
1122  ret i8 %r
1123}
1124
1125define <2 x i8> @not_ashr_vec(<2 x i8> %x) {
1126; CHECK-LABEL: @not_ashr_vec(
1127; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1)
1128; CHECK-NEXT:    [[R:%.*]] = sext <2 x i1> [[ISNOTNEG]] to <2 x i8>
1129; CHECK-NEXT:    ret <2 x i8> [[R]]
1130;
1131  %a = ashr <2 x i8> %x, <i8 7, i8 7>
1132  %r = xor <2 x i8> %a, <i8 -1, i8 -1>
1133  ret <2 x i8> %r
1134}
1135
1136define i8 @not_ashr_extra_use(i8 %x) {
1137; CHECK-LABEL: @not_ashr_extra_use(
1138; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 5
1139; CHECK-NEXT:    call void @use(i8 [[A]])
1140; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], -1
1141; CHECK-NEXT:    ret i8 [[R]]
1142;
1143  %a = ashr i8 %x, 5
1144  call void @use(i8 %a)
1145  %r = xor i8 %a, -1
1146  ret i8 %r
1147}
1148
1149define i8 @not_ashr_wrong_const(i8 %x) {
1150; CHECK-LABEL: @not_ashr_wrong_const(
1151; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 5
1152; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], -2
1153; CHECK-NEXT:    ret i8 [[R]]
1154;
1155  %a = ashr i8 %x, 5
1156  %r = xor i8 %a, -2
1157  ret i8 %r
1158}
1159
1160; (~A & B) ^ A --> A | B
1161
1162define <2 x i32> @xor_andn_commute1(<2 x i32> %a, <2 x i32> %b) {
1163; CHECK-LABEL: @xor_andn_commute1(
1164; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
1165; CHECK-NEXT:    ret <2 x i32> [[Z]]
1166;
1167  %nota = xor <2 x i32> %a, <i32 -1, i32 -1>
1168  %r = and <2 x i32> %nota, %b
1169  %z = xor <2 x i32> %r, %a
1170  ret <2 x i32> %z
1171}
1172
1173; (B & ~A) ^ A --> A | B
1174
1175define i33 @xor_andn_commute2(i33 %a, i33 %pb) {
1176; CHECK-LABEL: @xor_andn_commute2(
1177; CHECK-NEXT:    [[B:%.*]] = udiv i33 42, [[PB:%.*]]
1178; CHECK-NEXT:    [[Z:%.*]] = or i33 [[A:%.*]], [[B]]
1179; CHECK-NEXT:    ret i33 [[Z]]
1180;
1181  %b = udiv i33 42, %pb ; thwart complexity-based canonicalization
1182  %nota = xor i33 %a, -1
1183  %r = and i33 %b, %nota
1184  %z = xor i33 %r, %a
1185  ret i33 %z
1186}
1187
1188; A ^ (~A & B) --> A | B
1189
1190define i32 @xor_andn_commute3(i32 %pa, i32 %b) {
1191; CHECK-LABEL: @xor_andn_commute3(
1192; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA:%.*]]
1193; CHECK-NEXT:    [[Z:%.*]] = or i32 [[A]], [[B:%.*]]
1194; CHECK-NEXT:    ret i32 [[Z]]
1195;
1196  %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
1197  %nota = xor i32 %a, -1
1198  %r = and i32 %nota, %b
1199  %z = xor i32 %a, %r
1200  ret i32 %z
1201}
1202
1203; A ^ (B & ~A) --> A | B
1204
1205define i32 @xor_andn_commute4(i32 %pa, i32 %pb) {
1206; CHECK-LABEL: @xor_andn_commute4(
1207; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA:%.*]]
1208; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[PB:%.*]]
1209; CHECK-NEXT:    [[Z:%.*]] = or i32 [[A]], [[B]]
1210; CHECK-NEXT:    ret i32 [[Z]]
1211;
1212  %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
1213  %b = udiv i32 42, %pb ; thwart complexity-based canonicalization
1214  %nota = xor i32 %a, -1
1215  %r = and i32 %b, %nota
1216  %z = xor i32 %a, %r
1217  ret i32 %z
1218}
1219
1220; (~A | B) ^ A --> ~(A & B)
1221
1222define <2 x i64> @xor_orn(<2 x i64> %a, <2 x i64> %b) {
1223; CHECK-LABEL: @xor_orn(
1224; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i64> [[A:%.*]], [[B:%.*]]
1225; CHECK-NEXT:    [[Z:%.*]] = xor <2 x i64> [[TMP1]], splat (i64 -1)
1226; CHECK-NEXT:    ret <2 x i64> [[Z]]
1227;
1228  %nota = xor <2 x i64> %a, <i64 -1, i64 -1>
1229  %l = or <2 x i64> %nota, %b
1230  %z = xor <2 x i64> %l, %a
1231  ret <2 x i64> %z
1232}
1233
1234; A  ^ (~A | B) --> ~(A & B)
1235
1236define i8 @xor_orn_commute1(i8 %pa, i8 %b) {
1237; CHECK-LABEL: @xor_orn_commute1(
1238; CHECK-NEXT:    [[A:%.*]] = udiv i8 42, [[PA:%.*]]
1239; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A]], [[B:%.*]]
1240; CHECK-NEXT:    [[Z:%.*]] = xor i8 [[TMP1]], -1
1241; CHECK-NEXT:    ret i8 [[Z]]
1242;
1243  %a = udiv i8 42, %pa
1244  %nota = xor i8 %a, -1
1245  %l = or i8 %nota, %b
1246  %z = xor i8 %a, %l
1247  ret i8 %z
1248}
1249
1250; (B | ~A) ^ A --> ~(A & B)
1251
1252define i32 @xor_orn_commute2(i32 %a, i32 %pb,ptr %s) {
1253; CHECK-LABEL: @xor_orn_commute2(
1254; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[PB:%.*]]
1255; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B]]
1256; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[TMP1]], -1
1257; CHECK-NEXT:    ret i32 [[Z]]
1258;
1259  %b = udiv i32 42, %pb
1260  %nota = xor i32 %a, -1
1261  %l = or i32 %b, %nota
1262  %z = xor i32 %l, %a
1263  ret i32 %z
1264}
1265
1266define i32 @xor_orn_commute2_1use(i32 %a, i32 %pb,ptr %s) {
1267; CHECK-LABEL: @xor_orn_commute2_1use(
1268; CHECK-NEXT:    [[B:%.*]] = udiv i32 42, [[PB:%.*]]
1269; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A:%.*]], -1
1270; CHECK-NEXT:    store i32 [[NOTA]], ptr [[S:%.*]], align 4
1271; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A]], [[B]]
1272; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[TMP1]], -1
1273; CHECK-NEXT:    ret i32 [[Z]]
1274;
1275  %b = udiv i32 42, %pb
1276  %nota = xor i32 %a, -1
1277  %l = or i32 %b, %nota
1278  store i32 %nota, ptr %s
1279  %z = xor i32 %l, %a
1280  ret i32 %z
1281}
1282
1283; A ^ (B | ~A) --> ~(A & B)
1284
1285define i67 @xor_orn_commute3(i67 %pa, i67 %pb, ptr %s) {
1286; CHECK-LABEL: @xor_orn_commute3(
1287; CHECK-NEXT:    [[A:%.*]] = udiv i67 42, [[PA:%.*]]
1288; CHECK-NEXT:    [[B:%.*]] = udiv i67 42, [[PB:%.*]]
1289; CHECK-NEXT:    [[TMP1:%.*]] = and i67 [[A]], [[B]]
1290; CHECK-NEXT:    [[Z:%.*]] = xor i67 [[TMP1]], -1
1291; CHECK-NEXT:    ret i67 [[Z]]
1292;
1293  %a = udiv i67 42, %pa
1294  %b = udiv i67 42, %pb
1295  %nota = xor i67 %a, -1
1296  %l = or i67 %b, %nota
1297  %z = xor i67 %a, %l
1298  ret i67 %z
1299}
1300
1301define i67 @xor_orn_commute3_1use(i67 %pa, i67 %pb, ptr %s) {
1302; CHECK-LABEL: @xor_orn_commute3_1use(
1303; CHECK-NEXT:    [[A:%.*]] = udiv i67 42, [[PA:%.*]]
1304; CHECK-NEXT:    [[B:%.*]] = udiv i67 42, [[PB:%.*]]
1305; CHECK-NEXT:    [[NOTA:%.*]] = xor i67 [[A]], -1
1306; CHECK-NEXT:    [[L:%.*]] = or i67 [[B]], [[NOTA]]
1307; CHECK-NEXT:    store i67 [[L]], ptr [[S:%.*]], align 4
1308; CHECK-NEXT:    [[Z:%.*]] = xor i67 [[A]], [[L]]
1309; CHECK-NEXT:    ret i67 [[Z]]
1310;
1311  %a = udiv i67 42, %pa
1312  %b = udiv i67 42, %pb
1313  %nota = xor i67 %a, -1
1314  %l = or i67 %b, %nota
1315  store i67 %l, ptr %s
1316  %z = xor i67 %a, %l
1317  ret i67 %z
1318}
1319
1320define i32 @xor_orn_2use(i32 %a, i32 %b, ptr %s1, ptr %s2) {
1321; CHECK-LABEL: @xor_orn_2use(
1322; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A:%.*]], -1
1323; CHECK-NEXT:    store i32 [[NOTA]], ptr [[S1:%.*]], align 4
1324; CHECK-NEXT:    [[L:%.*]] = or i32 [[B:%.*]], [[NOTA]]
1325; CHECK-NEXT:    store i32 [[L]], ptr [[S2:%.*]], align 4
1326; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[L]], [[A]]
1327; CHECK-NEXT:    ret i32 [[Z]]
1328;
1329  %nota = xor i32 %a, -1
1330  store i32 %nota, ptr %s1
1331  %l = or i32 %nota, %b
1332  store i32 %l, ptr %s2
1333  %z = xor i32 %l, %a
1334  ret i32 %z
1335}
1336
1337define i32 @ctlz_pow2(i32 %x) {
1338; CHECK-LABEL: @ctlz_pow2(
1339; CHECK-NEXT:    [[R:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)
1340; CHECK-NEXT:    ret i32 [[R]]
1341;
1342  %n = sub i32 0, %x
1343  %a = and i32 %n, %x
1344  %z = call i32 @llvm.ctlz.i32(i32 %a, i1 true) ; 0 is poison
1345  %r = xor i32 %z, 31
1346  ret i32 %r
1347}
1348
1349; TODO: %d is known not zero, so this should fold even with arg1 set to false.
1350
1351define <2 x i8> @cttz_pow2(<2 x i8> %x, <2 x i8> %y) {
1352; CHECK-LABEL: @cttz_pow2(
1353; CHECK-NEXT:    [[S:%.*]] = shl nuw <2 x i8> splat (i8 1), [[X:%.*]]
1354; CHECK-NEXT:    [[D:%.*]] = udiv exact <2 x i8> [[S]], [[Y:%.*]]
1355; CHECK-NEXT:    [[R:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctlz.v2i8(<2 x i8> [[D]], i1 true)
1356; CHECK-NEXT:    ret <2 x i8> [[R]]
1357;
1358  %s = shl <2 x i8> <i8 1, i8 1>, %x
1359  %d = udiv exact <2 x i8> %s, %y
1360  %z = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %d, i1 true) ; 0 is poison
1361  %r = xor <2 x i8> %z, <i8 7, i8 7>
1362  ret <2 x i8> %r
1363}
1364
1365; negative test - 0 input returns 63
1366
1367define i32 @ctlz_pow2_or_zero(i32 %x) {
1368; CHECK-LABEL: @ctlz_pow2_or_zero(
1369; CHECK-NEXT:    [[N:%.*]] = sub i32 0, [[X:%.*]]
1370; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], [[N]]
1371; CHECK-NEXT:    [[Z:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[A]], i1 false)
1372; CHECK-NEXT:    [[R:%.*]] = xor i32 [[Z]], 31
1373; CHECK-NEXT:    ret i32 [[R]]
1374;
1375  %n = sub i32 0, %x
1376  %a = and i32 %n, %x
1377  %z = call i32 @llvm.ctlz.i32(i32 %a, i1 false) ; 0 is not poison
1378  %r = xor i32 %z, 31
1379  ret i32 %r
1380}
1381
1382; negative test - must xor with (bitwidth - 1)
1383
1384define i32 @ctlz_pow2_wrong_const(i32 %x) {
1385; CHECK-LABEL: @ctlz_pow2_wrong_const(
1386; CHECK-NEXT:    [[N:%.*]] = sub i32 0, [[X:%.*]]
1387; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], [[N]]
1388; CHECK-NEXT:    [[Z:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
1389; CHECK-NEXT:    [[R:%.*]] = xor i32 [[Z]], 30
1390; CHECK-NEXT:    ret i32 [[R]]
1391;
1392  %n = sub i32 0, %x
1393  %a = and i32 %n, %x
1394  %z = call i32 @llvm.ctlz.i32(i32 %a, i1 true) ; 0 is poison
1395  %r = xor i32 %z, 30
1396  ret i32 %r
1397}
1398
1399; Tests from PR70582
1400define i32 @tryFactorization_xor_ashr_lshr(i32 %a) {
1401; CHECK-LABEL: @tryFactorization_xor_ashr_lshr(
1402; CHECK-NEXT:    [[XOR:%.*]] = ashr i32 -8, [[A:%.*]]
1403; CHECK-NEXT:    ret i32 [[XOR]]
1404;
1405  %not = ashr i32 -3, %a
1406  %shr1 = lshr i32 5, %a
1407  %xor = xor i32 %not, %shr1
1408  ret i32 %xor
1409}
1410
1411define i32 @tryFactorization_xor_lshr_ashr(i32 %a) {
1412; CHECK-LABEL: @tryFactorization_xor_lshr_ashr(
1413; CHECK-NEXT:    [[XOR:%.*]] = ashr i32 -8, [[A:%.*]]
1414; CHECK-NEXT:    ret i32 [[XOR]]
1415;
1416  %not = ashr i32 -3, %a
1417  %shr1 = lshr i32 5, %a
1418  %xor = xor i32 %shr1, %not
1419  ret i32 %xor
1420}
1421
1422define i32 @tryFactorization_xor_ashr_lshr_negative_lhs(i32 %a) {
1423; CHECK-LABEL: @tryFactorization_xor_ashr_lshr_negative_lhs(
1424; CHECK-NEXT:    [[NOT:%.*]] = ashr i32 -3, [[A:%.*]]
1425; CHECK-NEXT:    [[SHR1:%.*]] = lshr i32 -5, [[A]]
1426; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NOT]], [[SHR1]]
1427; CHECK-NEXT:    ret i32 [[XOR]]
1428;
1429  %not = ashr i32 -3, %a
1430  %shr1 = lshr i32 -5, %a
1431  %xor = xor i32 %not, %shr1
1432  ret i32 %xor
1433}
1434
1435define i32 @tryFactorization_xor_lshr_lshr(i32 %a) {
1436; CHECK-LABEL: @tryFactorization_xor_lshr_lshr(
1437; CHECK-NEXT:    [[XOR:%.*]] = lshr i32 -8, [[A:%.*]]
1438; CHECK-NEXT:    ret i32 [[XOR]]
1439;
1440  %not = lshr i32 -3, %a
1441  %shr1 = lshr i32 5, %a
1442  %xor = xor i32 %not, %shr1
1443  ret i32 %xor
1444}
1445
1446define i32 @tryFactorization_xor_ashr_ashr(i32 %a) {
1447; CHECK-LABEL: @tryFactorization_xor_ashr_ashr(
1448; CHECK-NEXT:    [[XOR:%.*]] = lshr i32 6, [[A:%.*]]
1449; CHECK-NEXT:    ret i32 [[XOR]]
1450;
1451  %not = ashr i32 -3, %a
1452  %shr1 = ashr i32 -5, %a
1453  %xor = xor i32 %not, %shr1
1454  ret i32 %xor
1455}
1456
1457; https://alive2.llvm.org/ce/z/SOxv-e
1458define i4 @PR96857_xor_with_noundef(i4  %val0, i4  %val1, i4 noundef %val2) {
1459; CHECK-LABEL: @PR96857_xor_with_noundef(
1460; CHECK-NEXT:    [[VAL4:%.*]] = and i4 [[VAL2:%.*]], [[VAL0:%.*]]
1461; CHECK-NEXT:    [[VAL5:%.*]] = xor i4 [[VAL2]], -1
1462; CHECK-NEXT:    [[VAL6:%.*]] = and i4 [[VAL1:%.*]], [[VAL5]]
1463; CHECK-NEXT:    [[VAL7:%.*]] = or disjoint i4 [[VAL4]], [[VAL6]]
1464; CHECK-NEXT:    ret i4 [[VAL7]]
1465;
1466  %val4 = and i4 %val2, %val0
1467  %val5 = xor i4 %val2, -1
1468  %val6 = and i4 %val5, %val1
1469  %val7 = xor i4 %val4, %val6
1470  ret i4 %val7
1471}
1472
1473; https://alive2.llvm.org/ce/z/whLTaJ
1474define i4 @PR96857_xor_without_noundef(i4  %val0, i4  %val1, i4 %val2) {
1475; CHECK-LABEL: @PR96857_xor_without_noundef(
1476; CHECK-NEXT:    [[VAL4:%.*]] = and i4 [[VAL2:%.*]], [[VAL0:%.*]]
1477; CHECK-NEXT:    [[VAL5:%.*]] = xor i4 [[VAL2]], -1
1478; CHECK-NEXT:    [[VAL6:%.*]] = and i4 [[VAL1:%.*]], [[VAL5]]
1479; CHECK-NEXT:    [[VAL7:%.*]] = or i4 [[VAL4]], [[VAL6]]
1480; CHECK-NEXT:    ret i4 [[VAL7]]
1481;
1482  %val4 = and i4 %val2, %val0
1483  %val5 = xor i4 %val2, -1
1484  %val6 = and i4 %val5, %val1
1485  %val7 = xor i4 %val4, %val6
1486  ret i4 %val7
1487}
1488
1489define i32 @or_disjoint_with_xor(i32 %a, i32 %b) {
1490; CHECK-LABEL: @or_disjoint_with_xor(
1491; CHECK-NEXT:  entry:
1492; CHECK-NEXT:    ret i32 [[B:%.*]]
1493;
1494entry:
1495  %or = or disjoint i32 %a, %b
1496  %xor = xor i32 %or, %a
1497  ret i32 %xor
1498}
1499
1500define i32 @xor_with_or_disjoint_ab(i32 %a, i32 %b) {
1501; CHECK-LABEL: @xor_with_or_disjoint_ab(
1502; CHECK-NEXT:  entry:
1503; CHECK-NEXT:    ret i32 [[B:%.*]]
1504;
1505entry:
1506  %or = or disjoint i32 %a, %b
1507  %xor = xor i32 %a, %or
1508  ret i32 %xor
1509}
1510
1511define i32 @xor_with_or_disjoint_ba(i32 %a, i32 %b) {
1512; CHECK-LABEL: @xor_with_or_disjoint_ba(
1513; CHECK-NEXT:  entry:
1514; CHECK-NEXT:    ret i32 [[B:%.*]]
1515;
1516entry:
1517  %or = or disjoint i32 %b, %a
1518  %xor = xor i32 %b, %or
1519  ret i32 %xor
1520}
1521
1522define <2 x i32> @or_disjoint_with_xor_vec(<2 x i32> %a, < 2 x i32> %b) {
1523; CHECK-LABEL: @or_disjoint_with_xor_vec(
1524; CHECK-NEXT:  entry:
1525; CHECK-NEXT:    ret <2 x i32> [[B:%.*]]
1526;
1527entry:
1528  %or = or disjoint <2 x i32> %a, %b
1529  %xor = xor <2 x i32> %or, %a
1530  ret <2 x i32> %xor
1531}
1532
1533define <2 x i32> @xor_with_or_disjoint_vec(<2 x i32> %a, < 2 x i32> %b) {
1534; CHECK-LABEL: @xor_with_or_disjoint_vec(
1535; CHECK-NEXT:  entry:
1536; CHECK-NEXT:    ret <2 x i32> [[B:%.*]]
1537;
1538entry:
1539  %or = or disjoint <2 x i32> %a, %b
1540  %xor = xor <2 x i32> %a, %or
1541  ret <2 x i32> %xor
1542}
1543
1544define i32 @select_or_disjoint_xor(i32 %a, i1 %c) {
1545; CHECK-LABEL: @select_or_disjoint_xor(
1546; CHECK-NEXT:  entry:
1547; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], i32 0, i32 4
1548; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], 4
1549; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[S]], [[SHL]]
1550; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[OR]], 4
1551; CHECK-NEXT:    ret i32 [[XOR]]
1552;
1553entry:
1554  %s = select i1 %c, i32 0, i32 4
1555  %shl = shl i32 %a, 4
1556  %or = or disjoint i32 %s, %shl
1557  %xor = xor i32 %or, 4
1558  ret i32 %xor
1559}
1560
1561define <2 x i32> @select_or_disjoint_xor_vec(<2 x i32> %a, i1 %c) {
1562; CHECK-LABEL: @select_or_disjoint_xor_vec(
1563; CHECK-NEXT:  entry:
1564; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <2 x i32> zeroinitializer, <2 x i32> splat (i32 4)
1565; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 4)
1566; CHECK-NEXT:    [[OR:%.*]] = or disjoint <2 x i32> [[S]], [[SHL]]
1567; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[OR]], splat (i32 4)
1568; CHECK-NEXT:    ret <2 x i32> [[XOR]]
1569;
1570entry:
1571  %s = select i1 %c, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 4, i32 4>
1572  %shl = shl <2 x i32> %a, <i32 4, i32 4>
1573  %or = or <2 x i32> %s, %shl
1574  %xor = xor <2 x i32> %or, <i32 4, i32 4>
1575  ret <2 x i32> %xor
1576}
1577
1578define i32 @select_or_disjoint_or(i32 %a, i1 %c) {
1579; CHECK-LABEL: @select_or_disjoint_or(
1580; CHECK-NEXT:  entry:
1581; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], i32 0, i32 4
1582; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A:%.*]], 4
1583; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[S]], [[SHL]]
1584; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[OR]], 4
1585; CHECK-NEXT:    ret i32 [[ADD]]
1586;
1587entry:
1588  %s = select i1 %c, i32 0, i32 4
1589  %shl = shl i32 %a, 4
1590  %or = or disjoint i32 %s, %shl
1591  %add = add i32 %or, 4
1592  ret i32 %add
1593}
1594
1595define <2 x i32> @select_or_disjoint_or_vec(<2 x i32> %a, i1 %c) {
1596; CHECK-LABEL: @select_or_disjoint_or_vec(
1597; CHECK-NEXT:  entry:
1598; CHECK-NEXT:    [[S:%.*]] = select i1 [[C:%.*]], <2 x i32> zeroinitializer, <2 x i32> splat (i32 4)
1599; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 4)
1600; CHECK-NEXT:    [[OR:%.*]] = or disjoint <2 x i32> [[S]], [[SHL]]
1601; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i32> [[OR]], splat (i32 4)
1602; CHECK-NEXT:    ret <2 x i32> [[ADD]]
1603;
1604entry:
1605  %s = select i1 %c, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 4, i32 4>
1606  %shl = shl <2 x i32> %a, <i32 4, i32 4>
1607  %or = or <2 x i32> %s, %shl
1608  %add = add <2 x i32> %or, <i32 4, i32 4>
1609  ret <2 x i32> %add
1610}
1611
1612define i32 @or_multi_use_disjoint_with_xor(i32 %a, i32 %b, i32 %c) {
1613; CHECK-LABEL: @or_multi_use_disjoint_with_xor(
1614; CHECK-NEXT:  entry:
1615; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[A:%.*]], [[B:%.*]]
1616; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[OR]], [[C:%.*]]
1617; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[OR]], [[XOR]]
1618; CHECK-NEXT:    ret i32 [[ADD]]
1619;
1620entry:
1621  %or = or disjoint i32 %a, %b
1622  %xor = xor i32 %or, %c
1623  %add = add i32 %or, %xor
1624  ret i32 %add
1625}
1626
1627define <2 x i32> @or_multi_use_disjoint_with_xor_vec(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1628; CHECK-LABEL: @or_multi_use_disjoint_with_xor_vec(
1629; CHECK-NEXT:  entry:
1630; CHECK-NEXT:    [[OR:%.*]] = or disjoint <2 x i32> [[A:%.*]], [[B:%.*]]
1631; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[OR]], [[C:%.*]]
1632; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[OR]], [[XOR]]
1633; CHECK-NEXT:    ret <2 x i32> [[ADD]]
1634;
1635entry:
1636  %or = or disjoint <2 x i32> %a, %b
1637  %xor = xor <2 x i32> %or, %c
1638  %add = add <2 x i32> %or, %xor
1639  ret <2 x i32> %add
1640}
1641
1642define i32 @add_with_or(i32 %a, i32 %b, i32 %c) {
1643; CHECK-LABEL: @add_with_or(
1644; CHECK-NEXT:  entry:
1645; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1646; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ADD]], [[C:%.*]]
1647; CHECK-NEXT:    ret i32 [[OR]]
1648;
1649entry:
1650  %add = add i32 %a, %b
1651  %or = or i32 %add, %c
1652  ret i32 %or
1653}
1654
1655define <2 x i32> @add_with_or_vec(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1656; CHECK-LABEL: @add_with_or_vec(
1657; CHECK-NEXT:  entry:
1658; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[A:%.*]], [[B:%.*]]
1659; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ADD]], [[C:%.*]]
1660; CHECK-NEXT:    ret <2 x i32> [[OR]]
1661;
1662entry:
1663  %add = add <2 x i32> %a, %b
1664  %or = or <2 x i32> %add, %c
1665  ret <2 x i32> %or
1666}
1667