This handles expressions:
(~(a | b) & c) | ~(a | (b | c)) -> ~(a | b)
(~(a | b) & c) | ~(b | (a | c)) -> ~(a | b)
and swapped case:
(~(a & b) | c) & ~(a & (b & c)) -> ~(a & b)
(~(a & b) | c) & ~(b & (a & c)) -> ~(a & b)
The expression (~(a | b) & c) | ~((a | b) | c) is just an
(~x & c) | ~(x | c) and will be simplified without this
patch but two cases above need reassociation.
---------------------------------------- define i4 @src(i4 %a, i4 %b, i4 %c) { %0: %or1 = or i4 %c, %a %or2 = or i4 %or1, %b %not1 = xor i4 %or2, 15 %or3 = or i4 %a, %b %not2 = xor i4 %or3, 15 %and2 = and i4 %not2, %c %or4 = or i4 %and2, %not1 ret i4 %or4 } => define i4 @tgt(i4 %a, i4 %b, i4 %c) { %0: %or = or i4 %a, %b %not = xor i4 %or, 15 ret i4 %not } Transformation seems to be correct!
---------------------------------------- define i4 @src(i4 %a, i4 %b, i4 %c) { %0: %and1 = and i4 %c, %a %and2 = and i4 %and1, %b %not1 = xor i4 %and2, 15 %and3 = and i4 %a, %b %not2 = xor i4 %and3, 15 %or2 = or i4 %not2, %c %and4 = and i4 %or2, %not1 ret i4 %and4 } => define i4 @tgt(i4 %a, i4 %b, i4 %c) { %0: %and = and i4 %a, %b %not = xor i4 %and, 15 ret i4 %not } Transformation seems to be correct!