Details
- Reviewers
spatel craig.topper RKSimon javed.absar
Diff Detail
- Repository
- rL LLVM
Event Timeline
Hmm, and once i fix the vector handling, the same @test_andnotpd / @test_andnotps
in test/CodeGen/X86/{sse,sse2,avx}-schedule.ll break,
just like in the motivational case specified in D46031 :/
- Rebased ontop of revised tests
- Fix vector handling
- the same @test_andnotpd / @test_andnotps in test/CodeGen/X86/{sse,sse2,avx}-schedule.ll broke, just like in the motivational case specified in D46031 :/
- 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?
We are *almost* there..
I think this is the next step
I think we could handle D46031 first.
but we have to avoid regressing the x86 andnps tests?
Yes.
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?
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 |
In other words there seems to be only one case where we certainly should *not* transform.
Though we may want to also evaluate whether X is actually NOT(Y), and whether this transform would allow to fold that NOT into and.
Also, the inverse transform (the opposite of this differential) needs to be evaluated, if it helps to fold into andn.