This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Fold (A^B)|~A-->~(A&B)
ClosedPublic

Authored by MehrHeidar on Nov 12 2021, 10:24 AM.

Details

Summary

This patch fixes bug Failure to simplify (A^B)|~A --> ~(A&B) reported here:
https://bugs.llvm.org/show_bug.cgi?id=52478

Diff Detail

Event Timeline

MehrHeidar created this revision.Nov 12 2021, 10:24 AM
MehrHeidar requested review of this revision.Nov 12 2021, 10:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 12 2021, 10:24 AM
spatel added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2676

This surprised me, but this seems to work. Note that 'not' is also an 'xor' operation.
But canonicalization rules will always put the 'not' operand on the right (operand 1). So the swap above here then guarantees that the 'not' is operand 0.

llvm/test/Transforms/InstCombine/or-xor.ll
62

We need another test where X and Y are commuted.
We also need at least 3 tests with extra uses: (1) extra use of the 'not', (2) extra use of the regular 'xor', (3) extra uses of both of those.
The transform should be fine as long there is only one use for either of the operands because we are eliminating an instruction in this sequence.
When creating more tests, it's good to vary the data types a bit so we have better coverage. For example, have one test use vector types and another use a weird type like 'i65'.

Addressing review comments.

MehrHeidar added inline comments.Nov 13 2021, 10:42 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2676

Right, that is exactly the reason that I put the code after the swap in line 2671. If it is not appropriate I can change it.

llvm/test/Transforms/InstCombine/or-xor.ll
62

Thank you; I have added a few more tests based on your suggestion.

Modify name of one of the values in one of the test cases added in previous commit.

spatel added inline comments.Nov 14 2021, 6:06 AM
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2676

I think it's ok, but it would be nice to add the explanation to the code comment. So something like this:
// ~A | (A ^ B) -> ~(A & B) -- The swap above should always make Op0 the 'not'.

llvm/test/Transforms/InstCombine/or-xor.ll
62

Tests look good. Do you have commit access? If so, please pre-commit the tests with the baseline results, so we will show how the code changes in this patch.

Add a comment to clarify the Op0 in the or operation is guaranteed to be not in the foldable pattern due to the swap that is happening before.

MehrHeidar marked 4 inline comments as done.Nov 14 2021, 7:20 AM
MehrHeidar added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
2676

Thank you; I have added your suggested comment.

llvm/test/Transforms/InstCombine/or-xor.ll
62

No, I do not have commit access; But I prepared another patch to pre-commit the tests with baseline results here: https://reviews.llvm.org/D113846

If it's possible, Can you please commit it for me?
Thank you.

MehrHeidar marked 2 inline comments as done.

Rebase after pre-committing the test cases with base result.

spatel accepted this revision.Nov 15 2021, 8:40 AM

LGTM

Do you have enough commits/reviews now to request commit access? ( https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access )

This revision is now accepted and ready to land.Nov 15 2021, 8:40 AM

LGTM

Do you have enough commits/reviews now to request commit access? ( https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access )

Not yet, but I'll have soon. I guess after this one and D113861, I can request it.

This revision was automatically updated to reflect the committed changes.