Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[InstSimplify] Simplify the expression (a^c)&(a^~c) to zero and (a^c) | (a^~c) to minus one. #76637

Merged
merged 2 commits into from
Jan 3, 2024

Conversation

ChipsSpectre
Copy link
Contributor

@ChipsSpectre ChipsSpectre commented Dec 30, 2023

Changes the InstCombine pass of the LLVM optimizer, such that the aforementioned expression is reduced to zero if c2==~c1.
Alive2: https://alive2.llvm.org/ce/z/xkQiid
Fixes: #75692.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 30, 2023

@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: None (ChipsSpectre)

Changes

Changes the InstCombine pass of the LLVM optimizer, such that the aforementioned expression is reduced to zero if c2==~c1.

Fixes: #75692.


Full diff: https://github.com/llvm/llvm-project/pull/76637.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+7)
  • (modified) llvm/test/Transforms/InstCombine/and-xor-merge.ll (+11)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index c03f50d75814d8..a2e614998c4795 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2553,6 +2553,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
     if (match(Op1, m_c_Or(m_Not(m_Value(A)), m_Value(B))) &&
         match(Op0, m_c_Xor(m_Specific(A), m_Specific(B))))
       return BinaryOperator::CreateAnd(Builder.CreateNot(A), B);
+
+    ConstantInt *C1, *C2;
+    // (A ^ C1) & (A ^ C2) -> -1, if and only if C1 is inverted value of C2.
+    if (match(Op0, m_c_Xor(m_Value(A), m_ConstantInt(C1))) &&
+        match(Op1, m_c_Xor(m_Specific(A), m_ConstantInt(C2))) &&
+        C1->getValue() == ~C2->getValue())
+      return replaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
   }
 
   {
diff --git a/llvm/test/Transforms/InstCombine/and-xor-merge.ll b/llvm/test/Transforms/InstCombine/and-xor-merge.ll
index 543336468ff0a6..22c5a6737a55f4 100644
--- a/llvm/test/Transforms/InstCombine/and-xor-merge.ll
+++ b/llvm/test/Transforms/InstCombine/and-xor-merge.ll
@@ -40,3 +40,14 @@ define i32 @PR38781(i32 %a, i32 %b) {
   %and = and i32 %b.lobit.not, %a.lobit.not
   ret i32 %and
 }
+
+; (a ^ 4) & (a ^ ~4) -> 0
+define i32 @PR75692(i32 %x) {
+; CHECK-LABEL: @PR75692
+; CHECK-NEXT:  ret i32 0
+;
+  %t2 = xor i32 %x, 4
+  %t3 = xor i32 %x, -5
+  %t4 = and i32 %t2, %t3
+  ret i32 %t4
+}

@dtcxzyw dtcxzyw changed the title [llvm][Transforms] Reduce the expression (a^c1)&(a^c2) to zero, if possible [InstCombine] Reduce the expression (a^c1)&(a^~c1) to zero Dec 30, 2023
@dtcxzyw dtcxzyw changed the title [InstCombine] Reduce the expression (a^c1)&(a^~c1) to zero [InstSimplify] Simplify the expression (a^c)&(a^~c) to zero Dec 30, 2023
dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Jan 2, 2024
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add support for the conjugate or pattern at the same time.

Value *A;
// (A ^ C) & (A ^ ~C) -> 0
if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
match(Op1, m_Xor(m_Specific(A), m_APInt(C2))) && (*C1 ^ *C2).isAllOnes())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
match(Op1, m_Xor(m_Specific(A), m_APInt(C2))) && (*C1 ^ *C2).isAllOnes())
match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))

@ChipsSpectre
Copy link
Contributor Author

Please add support for the conjugate or pattern at the same time.

Can you explain what you mean with this?
I assume that you suggest adding support for the "or" pattern, i.e. (a ^ c1) | (a ^ c2) -> -1 and would add this.

@ChipsSpectre ChipsSpectre changed the title [InstSimplify] Simplify the expression (a^c)&(a^~c) to zero [InstSimplify] Simplify the expression (a^c)&(a^~c) to zero and (a^c) | (a^~c) to minus one. Jan 2, 2024
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

For the future, note that the second commit should contain test diffs. It seems like you committed the final test results directly into the first commit.

@ChipsSpectre
Copy link
Contributor Author

Thank you for your Review nikic.

Unfortunately, I do not have write access for this repository. Could you or dtcxzyw merge this pull request now?

@nikic nikic merged commit 4444a7e into llvm:main Jan 3, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

clang is suboptimal for (a ^ b) & (~a ^ b) where b is a specific constant
4 participants