diff options
| author | Craig Topper <craig.topper@gmail.com> | 2017-05-14 07:54:43 +0000 |
|---|---|---|
| committer | Craig Topper <craig.topper@gmail.com> | 2017-05-14 07:54:43 +0000 |
| commit | 479daaf74c6d0c5facdf2eceef06d5411c8bf322 (patch) | |
| tree | 88225be46c7eba2e0ec98c2ec63a5387f9f4819d /llvm/lib/Analysis | |
| parent | 982cc3b1d5b767b16d29197694ad17a108667407 (diff) | |
| download | bcm5719-llvm-479daaf74c6d0c5facdf2eceef06d5411c8bf322.tar.gz bcm5719-llvm-479daaf74c6d0c5facdf2eceef06d5411c8bf322.zip | |
[InstSimplify] Add patterns for folding (A & B) | (~A ^ B) -> (~A ^ B) and its commuted variants.
We already had (A & ~B) | (A ^ B), but we missed the cases where the not was part of the xor.
llvm-svn: 303004
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 1457422b255..6a1ec0f84e5 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1870,6 +1870,24 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, match(Op1, m_c_And(m_Not(m_Specific(A)), m_Specific(B))))) return Op0; + // (A & B) | (~A ^ B) -> (~A ^ B) + // (B & A) | (~A ^ B) -> (~A ^ B) + // (A & B) | (B ^ ~A) -> (B ^ ~A) + // (B & A) | (B ^ ~A) -> (B ^ ~A) + if (match(Op0, m_And(m_Value(A), m_Value(B))) && + (match(Op1, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) || + match(Op1, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B))))) + return Op1; + + // (~A ^ B) | (A & B) -> (~A ^ B) + // (~A ^ B) | (B & A) -> (~A ^ B) + // (B ^ ~A) | (A & B) -> (B ^ ~A) + // (B ^ ~A) | (B & A) -> (B ^ ~A) + if (match(Op1, m_And(m_Value(A), m_Value(B))) && + (match(Op0, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) || + match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B))))) + return Op0; + if (Value *V = simplifyAndOrOfICmps(Op0, Op1, false)) return V; |

