[PATCH] D113132: [InstCombine] Fuse checks for LHS (~(A | B) & C) | ... NFC.

Stanislav Mekhanoshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 8 15:38:49 PST 2021


rampitec added a comment.

In D113132#3112041 <https://reviews.llvm.org/D113132#3112041>, @spatel wrote:

> I think we need to step back before we add a bunch of other matches.
> For an expression with and/or/not, there should always be a Demorgan sibling where the and/or are swapped, right?
> https://alive2.llvm.org/ce/z/ziSbZa
>
> But we're transforming that into something that ends in 'xor', so it suggests we're missing some other 'xor' fold (and possibly another 'or' fold?).
>
> Can we generalize the existing transforms or at least group them so we don't have a mess of incomplete logic folds?

As far as I understand the difference between `visitOr` and `visintAnd` in this case: both are calling `InstCombinerImpl::SimplifyUsingDistributiveLaws`. The problem is:

For 'and' it creates `(~(a & c) | b) & (~(a & b))` -> `(a & b) ^ (~(a & c) | b)`. This is beneficial as it is one instruction less.
For 'or' it would create `(~(a | c) & b) | (~(a | b))` -> `~((a | b) ^ (~(a | c) & b))` using the same rules, same amount of operations, not beneficial.

The case `(a & b) ^ (~(a & c) | b)` -> `~(a & (b | c))` can use a separate match in the `visitXor` but given that extra 'not' operation which is created after swapping 'and' and 'or' operations in the source pattern I do not see how this can be generalized for a case where target is just one operation less and the same complexity if has to be inverted. In turn the pattern `(~(a | c) & b) | (~(a | b))` -> `~(a | (b & c))` saves a lot specifically due to its source complexity. I wish we have infrastructure though to express a pattern with swapped 'and' and 'or' in general.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113132/new/

https://reviews.llvm.org/D113132



More information about the llvm-commits mailing list