diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-05-02 14:48:23 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-05-02 14:48:23 +0000 |
commit | da0b4deafa21e2cd54a798c7cda4de7879a91fbd (patch) | |
tree | 612919445aa7ee2d39d9a7d83f1d826ea11d5c2b /llvm/lib | |
parent | 096a98198241c51822d246e3687831fff31700c7 (diff) | |
download | bcm5719-llvm-da0b4deafa21e2cd54a798c7cda4de7879a91fbd.tar.gz bcm5719-llvm-da0b4deafa21e2cd54a798c7cda4de7879a91fbd.zip |
revert r301923 : [InstCombine] don't use DeMorgan's Law on integer constants
There's a clang test that is wrongly using -O1 and failing after this commit.
llvm-svn: 301924
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index c7092bf3a39..41ae37ee127 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2433,32 +2433,29 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { if (Value *V = SimplifyBSwap(I)) return replaceInstUsesWith(I, V); - // Apply DeMorgan's Law for 'nand' / 'nor' logic with an inverted operand. - Value *X, *Y; - - // We must eliminate the and/or (one-use) for these transforms to not increase - // the instruction count. - // ~(~X & Y) --> (X | ~Y) - // ~(Y & ~X) --> (X | ~Y) - if (match(&I, m_Not(m_OneUse(m_c_And(m_Not(m_Value(X)), m_Value(Y)))))) { - Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not"); - return BinaryOperator::CreateOr(X, NotY); - } - // ~(~X | Y) --> (X & ~Y) - // ~(Y | ~X) --> (X & ~Y) - if (match(&I, m_Not(m_OneUse(m_c_Or(m_Not(m_Value(X)), m_Value(Y)))))) { - Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not"); - return BinaryOperator::CreateAnd(X, NotY); - } - // Is this a 'not' (~) fed by a binary operator? BinaryOperator *NotOp; if (match(&I, m_Not(m_BinOp(NotOp)))) { if (NotOp->getOpcode() == Instruction::And || NotOp->getOpcode() == Instruction::Or) { - // Apply DeMorgan's Law when inverts are free: - // ~(X & Y) --> (~X | ~Y) - // ~(X | Y) --> (~X & ~Y) + // We must eliminate the and/or for this transform to not increase the + // instruction count. + if (NotOp->hasOneUse()) { + // ~(~X & Y) --> (X | ~Y) - De Morgan's Law + // ~(~X | Y) === (X & ~Y) - De Morgan's Law + if (dyn_castNotVal(NotOp->getOperand(1))) + NotOp->swapOperands(); + if (Value *Op0NotVal = dyn_castNotVal(NotOp->getOperand(0))) { + Value *NotY = Builder->CreateNot( + NotOp->getOperand(1), NotOp->getOperand(1)->getName() + ".not"); + if (NotOp->getOpcode() == Instruction::And) + return BinaryOperator::CreateOr(Op0NotVal, NotY); + return BinaryOperator::CreateAnd(Op0NotVal, NotY); + } + } + + // ~(X & Y) --> (~X | ~Y) - De Morgan's Law + // ~(X | Y) === (~X & ~Y) - De Morgan's Law if (IsFreeToInvert(NotOp->getOperand(0), NotOp->getOperand(0)->hasOneUse()) && IsFreeToInvert(NotOp->getOperand(1), |