[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / demorgan.ll
blob2ec662cd131b51bb6a378cba3237781690b2d8f8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; (~A | ~B) == ~(A & B)
6 define 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]]
12   %NotA = xor i43 %A, -1
13   %NotB = xor i43 %B, -1
14   %C = or i43 %NotA, %NotB
15   ret i43 %C
18 ; (~A | ~B) == ~(A & B)
20 define 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]]
26   %NotA = xor i129 %A, -1
27   %NotB = xor i129 %B, -1
28   %C = or i129 %NotA, %NotB
29   ret i129 %C
32 ; (~A & ~B) == ~(A | B)
34 define 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]]
40   %NotA = xor i477 %A, -1
41   %NotB = xor i477 %B, -1
42   %C = and i477 %NotA, %NotB
43   ret i477 %C
46 ; (~A & ~B) == ~(A | B)
48 define 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]]
54   %NotA = xor i129 %A, -1
55   %NotB = xor i129 %B, -1
56   %C = and i129 %NotA, %NotB
57   ret i129 %C
60 ; (~A & ~B) == ~(A | B)
62 define 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]]
68   %NotA = xor i65 %A, -1
69   %NotB = xor i65 -1, %B
70   %C = and i65 %NotA, %NotB
71   ret i65 %C
74 ; (~A & ~B) == ~(A | B)
76 define 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]]
82   %NotA = xor i66 %A, -1
83   %NotB = xor i66 %B, -1
84   %C = and i66 %NotA, %NotB
85   ret i66 %C
88 ; (~A & ~B) == ~(A | B)
90 define 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]]
96   %NotA = xor i47 %A, -1
97   %NotB = xor i47 %B, -1
98   %C = and i47 %NotA, %NotB
99   ret i47 %C
102 ; This is confirming that 2 transforms work together:
103 ; ~(~A & ~B) --> A | B
105 define 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]]
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
117 ; Invert a constant if needed:
118 ; ~(~A & 5) --> A | ~5
120 define i32 @test4(i32 %A) {
121 ; CHECK-LABEL: @test4(
122 ; CHECK-NEXT:    [[NOTC1:%.*]] = or i32 [[A:%.*]], -6
123 ; CHECK-NEXT:    ret i32 [[NOTC1]]
125   %nota = xor i32 %A, -1
126   %c = and i32 %nota, 5
127   %notc = xor i32 %c, -1
128   ret i32 %notc
131 ; Test the mirror of DeMorgan's law with an extra 'not'.
132 ; ~(~A | ~B) --> A & B
134 define 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]]
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
146 ; Repeat with weird types for extra coverage.
147 ; ~(~A & ~B) --> A | B
149 define 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]]
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
161 ; ~(~A & 5) --> A | ~5
163 define 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]]
169   %nota = xor i61 %A, -1
170   %c = and i61 %nota, 5    ; 5 = ~c2
171   %notc = xor i61 %c, -1
172   ret i61 %c
175 ; ~(~A | ~B) --> A & B
177 define 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]]
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
189 ; ~(~A & B) --> (A | ~B)
191 define 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]]
197   %notx = xor i8 %A, -1
198   %c = and i8 %notx, %B
199   %notc = xor i8 %c, -1
200   ret i8 %notc
203 ; ~(~A & B) --> (A | ~B)
205 define 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]]
211   %nota = xor i7 %A, -1
212   %c = and i7 %nota, %B
213   %notc = xor i7 %c, -1
214   ret i7 %notc
217 ; ~(~A & B) --> (A | ~B)
219 define 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]]
225   %nota = xor i117 %A, -1
226   %c = and i117 %nota, %B
227   %notc = xor i117 %c, -1
228   ret i117 %notc
231 ; ~(~A | B) --> (A & ~B)
233 define 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]]
239   %notx = xor i8 %A, -1
240   %c = or i8 %notx, %B
241   %notc = xor i8 %c, -1
242   ret i8 %notc
245 ; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
247 define 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]]
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
264 ; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
266 define 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]]
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
282 ; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?
284 define 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]]
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
301 ; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
303 define 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]]
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
324 ; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
326 define 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]]
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
347 ; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?
349 define 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]]
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
370 ; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
372 define 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]]
378   %and = and i32 %a, 15
379   %and1 = xor i32 %and, -1
380   ret i32 %and1
383 ; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
385 define 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]]
391   %and = or i32 %a, 15
392   %and1 = xor i32 %and, -1
393   ret i32 %and1
396 ; PR22723: Recognize DeMorgan's Laws when obfuscated by zexts.
398 define 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]]
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
413 define 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]]
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
428 define <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]]
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
443 define <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]]
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
458 define 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]]
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
474 define 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]]
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
490 ; ~(~(a | b) | (a & b)) --> (a | b) & ~(a & b) -> a ^ b
492 define 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]]
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
505 define <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]]
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
518 ; (a ^ b) | ~(a | b) --> ~(a & b)
520 define 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]]
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