1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; (~A | ~B) == ~(A & B)
5
6define i43 @demorgan_or_apint1(i43 %A, i43 %B) {
7; CHECK-LABEL: @demorgan_or_apint1(
8; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i43 [[A:%.*]], [[B:%.*]]
9; CHECK-NEXT:    [[C:%.*]] = xor i43 [[C_DEMORGAN]], -1
10; CHECK-NEXT:    ret i43 [[C]]
11;
12  %NotA = xor i43 %A, -1
13  %NotB = xor i43 %B, -1
14  %C = or i43 %NotA, %NotB
15  ret i43 %C
16}
17
18; (~A | ~B) == ~(A & B)
19
20define i129 @demorgan_or_apint2(i129 %A, i129 %B) {
21; CHECK-LABEL: @demorgan_or_apint2(
22; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i129 [[A:%.*]], [[B:%.*]]
23; CHECK-NEXT:    [[C:%.*]] = xor i129 [[C_DEMORGAN]], -1
24; CHECK-NEXT:    ret i129 [[C]]
25;
26  %NotA = xor i129 %A, -1
27  %NotB = xor i129 %B, -1
28  %C = or i129 %NotA, %NotB
29  ret i129 %C
30}
31
32; (~A & ~B) == ~(A | B)
33
34define i477 @demorgan_and_apint1(i477 %A, i477 %B) {
35; CHECK-LABEL: @demorgan_and_apint1(
36; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i477 [[A:%.*]], [[B:%.*]]
37; CHECK-NEXT:    [[C:%.*]] = xor i477 [[C_DEMORGAN]], -1
38; CHECK-NEXT:    ret i477 [[C]]
39;
40  %NotA = xor i477 %A, -1
41  %NotB = xor i477 %B, -1
42  %C = and i477 %NotA, %NotB
43  ret i477 %C
44}
45
46; (~A & ~B) == ~(A | B)
47
48define i129 @demorgan_and_apint2(i129 %A, i129 %B) {
49; CHECK-LABEL: @demorgan_and_apint2(
50; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i129 [[A:%.*]], [[B:%.*]]
51; CHECK-NEXT:    [[C:%.*]] = xor i129 [[C_DEMORGAN]], -1
52; CHECK-NEXT:    ret i129 [[C]]
53;
54  %NotA = xor i129 %A, -1
55  %NotB = xor i129 %B, -1
56  %C = and i129 %NotA, %NotB
57  ret i129 %C
58}
59
60; (~A & ~B) == ~(A | B)
61
62define i65 @demorgan_and_apint3(i65 %A, i65 %B) {
63; CHECK-LABEL: @demorgan_and_apint3(
64; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i65 [[A:%.*]], [[B:%.*]]
65; CHECK-NEXT:    [[C:%.*]] = xor i65 [[C_DEMORGAN]], -1
66; CHECK-NEXT:    ret i65 [[C]]
67;
68  %NotA = xor i65 %A, -1
69  %NotB = xor i65 -1, %B
70  %C = and i65 %NotA, %NotB
71  ret i65 %C
72}
73
74; (~A & ~B) == ~(A | B)
75
76define i66 @demorgan_and_apint4(i66 %A, i66 %B) {
77; CHECK-LABEL: @demorgan_and_apint4(
78; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i66 [[A:%.*]], [[B:%.*]]
79; CHECK-NEXT:    [[C:%.*]] = xor i66 [[C_DEMORGAN]], -1
80; CHECK-NEXT:    ret i66 [[C]]
81;
82  %NotA = xor i66 %A, -1
83  %NotB = xor i66 %B, -1
84  %C = and i66 %NotA, %NotB
85  ret i66 %C
86}
87
88; (~A & ~B) == ~(A | B)
89
90define i47 @demorgan_and_apint5(i47 %A, i47 %B) {
91; CHECK-LABEL: @demorgan_and_apint5(
92; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i47 [[A:%.*]], [[B:%.*]]
93; CHECK-NEXT:    [[C:%.*]] = xor i47 [[C_DEMORGAN]], -1
94; CHECK-NEXT:    ret i47 [[C]]
95;
96  %NotA = xor i47 %A, -1
97  %NotB = xor i47 %B, -1
98  %C = and i47 %NotA, %NotB
99  ret i47 %C
100}
101
102; This is confirming that 2 transforms work together:
103; ~(~A & ~B) --> A | B
104
105define i32 @test3(i32 %A, i32 %B) {
106; CHECK-LABEL: @test3(
107; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
108; CHECK-NEXT:    ret i32 [[C_DEMORGAN]]
109;
110  %nota = xor i32 %A, -1
111  %notb = xor i32 %B, -1
112  %c = and i32 %nota, %notb
113  %notc = xor i32 %c, -1
114  ret i32 %notc
115}
116
117; Invert a constant if needed:
118; ~(~A & 5) --> A | ~5
119
120define i32 @test4(i32 %A) {
121; CHECK-LABEL: @test4(
122; CHECK-NEXT:    [[NOTC1:%.*]] = or i32 [[A:%.*]], -6
123; CHECK-NEXT:    ret i32 [[NOTC1]]
124;
125  %nota = xor i32 %A, -1
126  %c = and i32 %nota, 5
127  %notc = xor i32 %c, -1
128  ret i32 %notc
129}
130
131; Test the mirror of DeMorgan's law with an extra 'not'.
132; ~(~A | ~B) --> A & B
133
134define i32 @test5(i32 %A, i32 %B) {
135; CHECK-LABEL: @test5(
136; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
137; CHECK-NEXT:    ret i32 [[C_DEMORGAN]]
138;
139  %nota = xor i32 %A, -1
140  %notb = xor i32 %B, -1
141  %c = or i32 %nota, %notb
142  %notc = xor i32 %c, -1
143  ret i32 %notc
144}
145
146; Repeat with weird types for extra coverage.
147; ~(~A & ~B) --> A | B
148
149define i47 @test3_apint(i47 %A, i47 %B) {
150; CHECK-LABEL: @test3_apint(
151; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i47 [[A:%.*]], [[B:%.*]]
152; CHECK-NEXT:    ret i47 [[C_DEMORGAN]]
153;
154  %nota = xor i47 %A, -1
155  %notb = xor i47 %B, -1
156  %c = and i47 %nota, %notb
157  %notc = xor i47 %c, -1
158  ret i47 %notc
159}
160
161; ~(~A & 5) --> A | ~5
162
163define i61 @test4_apint(i61 %A) {
164; CHECK-LABEL: @test4_apint(
165; CHECK-NEXT:    [[NOTA:%.*]] = and i61 [[A:%.*]], 5
166; CHECK-NEXT:    [[C:%.*]] = xor i61 [[NOTA]], 5
167; CHECK-NEXT:    ret i61 [[C]]
168;
169  %nota = xor i61 %A, -1
170  %c = and i61 %nota, 5    ; 5 = ~c2
171  %notc = xor i61 %c, -1
172  ret i61 %c
173}
174
175; ~(~A | ~B) --> A & B
176
177define i71 @test5_apint(i71 %A, i71 %B) {
178; CHECK-LABEL: @test5_apint(
179; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i71 [[A:%.*]], [[B:%.*]]
180; CHECK-NEXT:    ret i71 [[C_DEMORGAN]]
181;
182  %nota = xor i71 %A, -1
183  %notb = xor i71 %B, -1
184  %c = or i71 %nota, %notb
185  %notc = xor i71 %c, -1
186  ret i71 %notc
187}
188
189; ~(~A & B) --> (A | ~B)
190
191define i8 @demorgan_nand(i8 %A, i8 %B) {
192; CHECK-LABEL: @demorgan_nand(
193; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1
194; CHECK-NEXT:    [[NOTC:%.*]] = or i8 [[B_NOT]], [[A:%.*]]
195; CHECK-NEXT:    ret i8 [[NOTC]]
196;
197  %notx = xor i8 %A, -1
198  %c = and i8 %notx, %B
199  %notc = xor i8 %c, -1
200  ret i8 %notc
201}
202
203; ~(~A & B) --> (A | ~B)
204
205define i7 @demorgan_nand_apint1(i7 %A, i7 %B) {
206; CHECK-LABEL: @demorgan_nand_apint1(
207; CHECK-NEXT:    [[B_NOT:%.*]] = xor i7 [[B:%.*]], -1
208; CHECK-NEXT:    [[NOTC:%.*]] = or i7 [[B_NOT]], [[A:%.*]]
209; CHECK-NEXT:    ret i7 [[NOTC]]
210;
211  %nota = xor i7 %A, -1
212  %c = and i7 %nota, %B
213  %notc = xor i7 %c, -1
214  ret i7 %notc
215}
216
217; ~(~A & B) --> (A | ~B)
218
219define i117 @demorgan_nand_apint2(i117 %A, i117 %B) {
220; CHECK-LABEL: @demorgan_nand_apint2(
221; CHECK-NEXT:    [[B_NOT:%.*]] = xor i117 [[B:%.*]], -1
222; CHECK-NEXT:    [[NOTC:%.*]] = or i117 [[B_NOT]], [[A:%.*]]
223; CHECK-NEXT:    ret i117 [[NOTC]]
224;
225  %nota = xor i117 %A, -1
226  %c = and i117 %nota, %B
227  %notc = xor i117 %c, -1
228  ret i117 %notc
229}
230
231; ~(~A | B) --> (A & ~B)
232
233define i8 @demorgan_nor(i8 %A, i8 %B) {
234; CHECK-LABEL: @demorgan_nor(
235; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1
236; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[B_NOT]], [[A:%.*]]
237; CHECK-NEXT:    ret i8 [[NOTC]]
238;
239  %notx = xor i8 %A, -1
240  %c = or i8 %notx, %B
241  %notc = xor i8 %c, -1
242  ret i8 %notc
243}
244
245; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
246
247define i8 @demorgan_nor_use2a(i8 %A, i8 %B) {
248; CHECK-LABEL: @demorgan_nor_use2a(
249; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1
250; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 23
251; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1
252; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[B_NOT]], [[A]]
253; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2A]]
254; CHECK-NEXT:    ret i8 [[R]]
255;
256  %nota = xor i8 %A, -1
257  %use2a = mul i8 %nota, 23
258  %c = or i8 %nota, %B
259  %notc = xor i8 %c, -1
260  %r = sdiv i8 %notc, %use2a
261  ret i8 %r
262}
263
264; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
265
266define i8 @demorgan_nor_use2b(i8 %A, i8 %B) {
267; CHECK-LABEL: @demorgan_nor_use2b(
268; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23
269; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B]], -1
270; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[B_NOT]], [[A:%.*]]
271; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2B]]
272; CHECK-NEXT:    ret i8 [[R]]
273;
274  %use2b = mul i8 %B, 23
275  %nota = xor i8 %A, -1
276  %c = or i8 %nota, %B
277  %notc = xor i8 %c, -1
278  %r = sdiv i8 %notc, %use2b
279  ret i8 %r
280}
281
282; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
283
284define i8 @demorgan_nor_use2c(i8 %A, i8 %B) {
285; CHECK-LABEL: @demorgan_nor_use2c(
286; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1
287; CHECK-NEXT:    [[C:%.*]] = or i8 [[NOTA]], [[B:%.*]]
288; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23
289; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1
290; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]
291; CHECK-NEXT:    ret i8 [[R]]
292;
293  %nota = xor i8 %A, -1
294  %c = or i8 %nota, %B
295  %use2c = mul i8 %c, 23
296  %notc = xor i8 %c, -1
297  %r = sdiv i8 %notc, %use2c
298  ret i8 %r
299}
300
301; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
302
303define i8 @demorgan_nor_use2ab(i8 %A, i8 %B) {
304; CHECK-LABEL: @demorgan_nor_use2ab(
305; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23
306; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1
307; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 17
308; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B]], -1
309; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[B_NOT]], [[A]]
310; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2B]]
311; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]]
312; CHECK-NEXT:    ret i8 [[R2]]
313;
314  %use2b = mul i8 %B, 23
315  %nota = xor i8 %A, -1
316  %use2a = mul i8 %nota, 17
317  %c = or i8 %nota, %B
318  %notc = xor i8 %c, -1
319  %r1 = sdiv i8 %notc, %use2b
320  %r2 = sdiv i8 %r1, %use2a
321  ret i8 %r2
322}
323
324; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
325
326define i8 @demorgan_nor_use2ac(i8 %A, i8 %B) {
327; CHECK-LABEL: @demorgan_nor_use2ac(
328; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1
329; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 17
330; CHECK-NEXT:    [[C:%.*]] = or i8 [[NOTA]], [[B:%.*]]
331; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23
332; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1
333; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]
334; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]]
335; CHECK-NEXT:    ret i8 [[R2]]
336;
337  %nota = xor i8 %A, -1
338  %use2a = mul i8 %nota, 17
339  %c = or i8 %nota, %B
340  %use2c = mul i8 %c, 23
341  %notc = xor i8 %c, -1
342  %r1 = sdiv i8 %notc, %use2c
343  %r2 = sdiv i8 %r1, %use2a
344  ret i8 %r2
345}
346
347; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
348
349define i8 @demorgan_nor_use2bc(i8 %A, i8 %B) {
350; CHECK-LABEL: @demorgan_nor_use2bc(
351; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23
352; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1
353; CHECK-NEXT:    [[C:%.*]] = or i8 [[NOTA]], [[B]]
354; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23
355; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1
356; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]
357; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2B]]
358; CHECK-NEXT:    ret i8 [[R2]]
359;
360  %use2b = mul i8 %B, 23
361  %nota = xor i8 %A, -1
362  %c = or i8 %nota, %B
363  %use2c = mul i8 %c, 23
364  %notc = xor i8 %c, -1
365  %r1 = sdiv i8 %notc, %use2c
366  %r2 = sdiv i8 %r1, %use2b
367  ret i8 %r2
368}
369
370; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
371
372define i32 @demorganize_constant1(i32 %a) {
373; CHECK-LABEL: @demorganize_constant1(
374; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 15
375; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[AND]], -1
376; CHECK-NEXT:    ret i32 [[AND1]]
377;
378  %and = and i32 %a, 15
379  %and1 = xor i32 %and, -1
380  ret i32 %and1
381}
382
383; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
384
385define i32 @demorganize_constant2(i32 %a) {
386; CHECK-LABEL: @demorganize_constant2(
387; CHECK-NEXT:    [[AND:%.*]] = or i32 [[A:%.*]], 15
388; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[AND]], -1
389; CHECK-NEXT:    ret i32 [[AND1]]
390;
391  %and = or i32 %a, 15
392  %and1 = xor i32 %and, -1
393  ret i32 %and1
394}
395
396; PR22723: Recognize DeMorgan's Laws when obfuscated by zexts.
397
398define i32 @demorgan_or_zext(i1 %X, i1 %Y) {
399; CHECK-LABEL: @demorgan_or_zext(
400; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
401; CHECK-NEXT:    [[OR1:%.*]] = xor i1 [[OR1_DEMORGAN]], true
402; CHECK-NEXT:    [[OR:%.*]] = zext i1 [[OR1]] to i32
403; CHECK-NEXT:    ret i32 [[OR]]
404;
405  %zextX = zext i1 %X to i32
406  %zextY = zext i1 %Y to i32
407  %notX  = xor i32 %zextX, 1
408  %notY  = xor i32 %zextY, 1
409  %or    = or i32 %notX, %notY
410  ret i32 %or
411}
412
413define i32 @demorgan_and_zext(i1 %X, i1 %Y) {
414; CHECK-LABEL: @demorgan_and_zext(
415; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
416; CHECK-NEXT:    [[AND1:%.*]] = xor i1 [[AND1_DEMORGAN]], true
417; CHECK-NEXT:    [[AND:%.*]] = zext i1 [[AND1]] to i32
418; CHECK-NEXT:    ret i32 [[AND]]
419;
420  %zextX = zext i1 %X to i32
421  %zextY = zext i1 %Y to i32
422  %notX  = xor i32 %zextX, 1
423  %notY  = xor i32 %zextY, 1
424  %and   = and i32 %notX, %notY
425  ret i32 %and
426}
427
428define <2 x i32> @demorgan_or_zext_vec(<2 x i1> %X, <2 x i1> %Y) {
429; CHECK-LABEL: @demorgan_or_zext_vec(
430; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and <2 x i1> [[X:%.*]], [[Y:%.*]]
431; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i1> [[OR1_DEMORGAN]], <i1 true, i1 true>
432; CHECK-NEXT:    [[OR:%.*]] = zext <2 x i1> [[OR1]] to <2 x i32>
433; CHECK-NEXT:    ret <2 x i32> [[OR]]
434;
435  %zextX = zext <2 x i1> %X to <2 x i32>
436  %zextY = zext <2 x i1> %Y to <2 x i32>
437  %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>
438  %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>
439  %or    = or <2 x i32> %notX, %notY
440  ret <2 x i32> %or
441}
442
443define <2 x i32> @demorgan_and_zext_vec(<2 x i1> %X, <2 x i1> %Y) {
444; CHECK-LABEL: @demorgan_and_zext_vec(
445; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]]
446; CHECK-NEXT:    [[AND1:%.*]] = xor <2 x i1> [[AND1_DEMORGAN]], <i1 true, i1 true>
447; CHECK-NEXT:    [[AND:%.*]] = zext <2 x i1> [[AND1]] to <2 x i32>
448; CHECK-NEXT:    ret <2 x i32> [[AND]]
449;
450  %zextX = zext <2 x i1> %X to <2 x i32>
451  %zextY = zext <2 x i1> %Y to <2 x i32>
452  %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>
453  %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>
454  %and   = and <2 x i32> %notX, %notY
455  ret <2 x i32> %and
456}
457
458define i32 @PR28476(i32 %x, i32 %y) {
459; CHECK-LABEL: @PR28476(
460; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
461; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 0
462; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[CMP0]], [[CMP1]]
463; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[TMP1]] to i32
464; CHECK-NEXT:    ret i32 [[COND]]
465;
466  %cmp0 = icmp ne i32 %x, 0
467  %cmp1 = icmp ne i32 %y, 0
468  %and = and i1 %cmp0, %cmp1
469  %zext = zext i1 %and to i32
470  %cond = xor i32 %zext, 1
471  ret i32 %cond
472}
473
474define i32 @PR28476_logical(i32 %x, i32 %y) {
475; CHECK-LABEL: @PR28476_logical(
476; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
477; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 0
478; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP0]], i1 true, i1 [[CMP1]]
479; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[AND]] to i32
480; CHECK-NEXT:    ret i32 [[COND]]
481;
482  %cmp0 = icmp ne i32 %x, 0
483  %cmp1 = icmp ne i32 %y, 0
484  %and = select i1 %cmp0, i1 %cmp1, i1 false
485  %zext = zext i1 %and to i32
486  %cond = xor i32 %zext, 1
487  ret i32 %cond
488}
489
490; ~(~(a | b) | (a & b)) --> (a | b) & ~(a & b) -> a ^ b
491
492define i32 @demorgan_plus_and_to_xor(i32 %a, i32 %b) {
493; CHECK-LABEL: @demorgan_plus_and_to_xor(
494; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
495; CHECK-NEXT:    ret i32 [[TMP1]]
496;
497  %or = or i32 %b, %a
498  %notor = xor i32 %or, -1
499  %and = and i32 %b, %a
500  %or2 = or i32 %and, %notor
501  %not = xor i32 %or2, -1
502  ret i32 %not
503}
504
505define <4 x i32> @demorgan_plus_and_to_xor_vec(<4 x i32> %a, <4 x i32> %b) {
506; CHECK-LABEL: @demorgan_plus_and_to_xor_vec(
507; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i32> [[A:%.*]], [[B:%.*]]
508; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
509;
510  %or = or <4 x i32> %a, %b
511  %notor = xor <4 x i32> %or, < i32 -1, i32 -1, i32 -1, i32 -1 >
512  %and = and <4 x i32> %a, %b
513  %or2 = or <4 x i32> %and, %notor
514  %not = xor <4 x i32> %or2, < i32 -1, i32 -1, i32 -1, i32 -1 >
515  ret <4 x i32> %not
516}
517
518; (a ^ b) | ~(a | b) --> ~(a & b)
519
520define i32 @PR45984(i32 %0, i32 %1) {
521; CHECK-LABEL: @PR45984(
522; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP1:%.*]], [[TMP0:%.*]]
523; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1
524; CHECK-NEXT:    ret i32 [[TMP4]]
525;
526  %3 = xor i32 %1, %0
527  %4 = or i32 %1, %0
528  %5 = xor i32 %4, -1
529  %6 = or i32 %3, %5
530  ret i32 %6
531}
532