[PATCH] D46073: [DagCombine] De Morgan laws: 'nand' logic with an inverted operand

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 3 10:49:52 PDT 2018


lebedev.ri added a comment.

In https://reviews.llvm.org/D46073#1085463, @spatel wrote:

> In https://reviews.llvm.org/D46073#1080839, @lebedev.ri wrote:
>
> > - Rebased ontop of revised tests.
> > - Handle `nor` pattern too.
> > - Still not sure how to handle `vandnpd`/`vandnps` breakage.
>
>
> I lost track of where we are in the masked merge odyssey. :)
>  I think this is the next step, but we have to avoid regressing the x86 andnps tests?




> Can we use TLI.hasAndNot() to predicate the transform? Ie, if you have 'andn', then there's no point trying to eliminate a 'not' that will get merged with another instruction?

I think this would need to be a bit more complex. E.g.:

- if this `not` is used in `and`, and the other hand of `and` ...
  - ... is ok as per `hasAndNot()` (i.e. in x86's case, not an immediate), then there is no immediate benefit of simplification. `[A]`
  - ... is not ok as per `hasAndNot()` (i.e. in x86's case, e.g. an immediate), then we shouldn't at least degrade the code by simplifying. `[B]`
- else, if it is used elsewhere (not in `and`), then we shouldn't at least degrade the code by simplifying. `[B]`
- We have two patterns. (Let's look at the inner `and`/`or`):
  - `~(~A & B) --> (A | ~B)` <- the original form *may*  `[00]` or may not `[01]` get folded into `andn`, the transformed variant is unlikely to be folded (`ORN: logical OR NOT (Thumb only)`).
  - `~(~A | B) --> (A & ~B)` <- the original form is unlikely to be folded into `orn`, the transformed variant *may* `[10]` or may not `[11]` to be folded. `[1]`

So we have 8 variants: (`X` being the other hand)

| from                          | to                         | delta                  |
| `OP   X, not(and(not(A), B))` | `OP  X,  or   (A, not(B))` | 3 -> 2, **transform**  |
| `OP   X, not(andn(A, B))`     | `OP  X,  or   (A, not(B))` | 2 -> 2, keep           |
| `andn X, and(not(A), B)`      | `and X,  or   (A, not(B))` | 2 -> 2, keep           |
| `andn X, andn(A, B)`          | `and X,  or   (A, not(B))` | 1 -> 2, keep!          |
| `OP   X, not(or(not(A), B))`  | `OP X,   and  (A, not(B))` | 3 -> 2, **transform**  |
| `OP   X, not(or(not(A), B))`  | `OP X,   andn (A, B)`      | 3 -> 1, **transform!** |
| `andn X, or(not(A), B)`       | `and X,  and  (A, not(B))` | 2 -> 2, keep           |
| `andn X, or(not(A), B)`       | `and X,  andn (A, B)`      | 2 -> 1, **transform**  |
|


Repository:
  rL LLVM

https://reviews.llvm.org/D46073





More information about the llvm-commits mailing list