diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-09-06 16:23:40 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-09-06 16:23:40 +0000 |
commit | 93bd15a00593286ebbd904b66a4b1575ccce7762 (patch) | |
tree | 3c7b6d7beaa482d1408ef5d95cb184233e629abc /llvm/lib | |
parent | 29200611055f49a0d37243caa5f8bba1df9d57a6 (diff) | |
download | bcm5719-llvm-93bd15a00593286ebbd904b66a4b1575ccce7762.tar.gz bcm5719-llvm-93bd15a00593286ebbd904b66a4b1575ccce7762.zip |
[InstCombine] add xor+not folds
This fold is needed to avoid a regression when we try
to recommit rL300977.
We can't see the most basic win currently because
demanded bits changes the patterns:
https://rise4fun.com/Alive/plpp
llvm-svn: 341559
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 9e6f09dab3c..bbe4b9b8556 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2702,6 +2702,22 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return BinaryOperator::CreateSub(ConstantExpr::getNeg(AddOne(C)), X); } + // Use DeMorgan and reassociation to eliminate a 'not' op. + Constant *C1; + if (match(Op1, m_Constant(C1))) { + Constant *C2; + if (match(Op0, m_OneUse(m_Or(m_Not(m_Value(X)), m_Constant(C2))))) { + // (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1 + Value *And = Builder.CreateAnd(X, ConstantExpr::getNot(C2)); + return BinaryOperator::CreateXor(And, ConstantExpr::getNot(C1)); + } + if (match(Op0, m_OneUse(m_And(m_Not(m_Value(X)), m_Constant(C2))))) { + // (~X & C2) ^ C1 --> ((X | ~C2) ^ -1) ^ C1 --> (X | ~C2) ^ ~C1 + Value *Or = Builder.CreateOr(X, ConstantExpr::getNot(C2)); + return BinaryOperator::CreateXor(Or, ConstantExpr::getNot(C1)); + } + } + // not (cmp A, B) = !cmp A, B CmpInst::Predicate Pred; if (match(&I, m_Not(m_OneUse(m_Cmp(Pred, m_Value(), m_Value()))))) { |