diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:32:43 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:32:43 +0000 | 
| commit | b7eb8e35e481a74962664b63dfb09483b200209a (patch) | |
| tree | 1937fb4a348458ce2d02ade03ac3bb0aa18d2fcd /lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
| parent | eb11fae6d08f479c0799db45860a98af528fa6e7 (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 32 | 
1 files changed, 7 insertions, 25 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 372bc41f780e2..3d758e2fe7c97 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1550,31 +1550,13 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {      return DeMorgan;    { -    Value *A = nullptr, *B = nullptr, *C = nullptr; -    // A&(A^B) => A & ~B -    { -      Value *tmpOp0 = Op0; -      Value *tmpOp1 = Op1; -      if (match(Op0, m_OneUse(m_Xor(m_Value(A), m_Value(B))))) { -        if (A == Op1 || B == Op1 ) { -          tmpOp1 = Op0; -          tmpOp0 = Op1; -          // Simplify below -        } -      } - -      if (match(tmpOp1, m_OneUse(m_Xor(m_Value(A), m_Value(B))))) { -        if (B == tmpOp0) { -          std::swap(A, B); -        } -        // Notice that the pattern (A&(~B)) is actually (A&(-1^B)), so if -        // A is originally -1 (or a vector of -1 and undefs), then we enter -        // an endless loop. By checking that A is non-constant we ensure that -        // we will never get to the loop. -        if (A == tmpOp0 && !isa<Constant>(A)) // A&(A^B) -> A & ~B -          return BinaryOperator::CreateAnd(A, Builder.CreateNot(B)); -      } -    } +    Value *A, *B, *C; +    // A & (A ^ B) --> A & ~B +    if (match(Op1, m_OneUse(m_c_Xor(m_Specific(Op0), m_Value(B))))) +      return BinaryOperator::CreateAnd(Op0, Builder.CreateNot(B)); +    // (A ^ B) & A --> A & ~B +    if (match(Op0, m_OneUse(m_c_Xor(m_Specific(Op1), m_Value(B))))) +      return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(B));      // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C      if (match(Op0, m_Xor(m_Value(A), m_Value(B))))  | 
