Author: Roman Lebedev Date: 2020-12-24T21:20:49+03:00 New Revision: 5b78303433c0778a839e89d20daa57fbc037d0c7
URL: https://github.com/llvm/llvm-project/commit/5b78303433c0778a839e89d20daa57fbc037d0c7 DIFF: https://github.com/llvm/llvm-project/commit/5b78303433c0778a839e89d20daa57fbc037d0c7.diff LOG: [InstCombine] Fold `a & ~(a ^ b)` to `x & y` ``` ---------------------------------------- define i32 @and_xor_not_common_op(i32 %a, i32 %b) { %0: %b2 = xor i32 %b, 4294967295 %t2 = xor i32 %a, %b2 %t4 = and i32 %t2, %a ret i32 %t4 } => define i32 @and_xor_not_common_op(i32 %a, i32 %b) { %0: %t4 = and i32 %a, %b ret i32 %t4 } Transformation seems to be correct! ``` Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/test/Transforms/InstCombine/and-xor-or.ll Removed: ################################################################################ diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 6b5fd571ecf5..3c0cdaf6e843 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1883,6 +1883,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) { if (match(Op0, m_OneUse(m_c_Xor(m_Specific(Op1), m_Value(B))))) return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(B)); + // A & ~(A ^ B) --> A & B + if (match(Op1, m_Not(m_c_Xor(m_Specific(Op0), m_Value(B))))) + return BinaryOperator::CreateAnd(Op0, B); + // ~(A ^ B) & A --> A & B + if (match(Op0, m_Not(m_c_Xor(m_Specific(Op1), m_Value(B))))) + return BinaryOperator::CreateAnd(Op1, B); + // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A)))) diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll index 4a27e3f00c89..4cb88d0766ba 100644 --- a/llvm/test/Transforms/InstCombine/and-xor-or.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll @@ -116,9 +116,7 @@ define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, i32* %dst) { define i32 @and_not_xor_common_op(i32 %a, i32 %b) { ; CHECK-LABEL: @and_not_xor_common_op( -; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[T2:%.*]] = xor i32 [[B2]], -1 -; CHECK-NEXT: [[T4:%.*]] = and i32 [[T2]], [[A]] +; CHECK-NEXT: [[T4:%.*]] = and i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: ret i32 [[T4]] ; %b2 = xor i32 %b, %a @@ -131,9 +129,7 @@ declare i32 @gen32() define i32 @and_not_xor_common_op_commutative(i32 %b) { ; CHECK-LABEL: @and_not_xor_common_op_commutative( ; CHECK-NEXT: [[A:%.*]] = call i32 @gen32() -; CHECK-NEXT: [[B2:%.*]] = xor i32 [[A]], [[B:%.*]] -; CHECK-NEXT: [[T2:%.*]] = xor i32 [[B2]], -1 -; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[T2]] +; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B:%.*]] ; CHECK-NEXT: ret i32 [[T4]] ; %a = call i32 @gen32() _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits