diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-07-15 17:26:01 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-07-15 17:26:01 +0000 |
commit | 3437ee27407d9fe27155000930a324d1022b781d (patch) | |
tree | eebf814b61dc67fcbf9ede6a358e19e2dd43d58b /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
parent | e29b112f493cab1cbf5f9a6ed5e8d1ea26f98176 (diff) | |
download | bcm5719-llvm-3437ee27407d9fe27155000930a324d1022b781d.tar.gz bcm5719-llvm-3437ee27407d9fe27155000930a324d1022b781d.zip |
[InstCombine] improve (1 << x) & 1 --> zext(x == 0) folding
1. Add a one-use check to prevent increasing instruction count.
2. Generalize the pattern matching to include vector types.
llvm-svn: 308105
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index e8560099f9d..6f0703178f3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1284,10 +1284,19 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (Value *V = SimplifyBSwap(I, Builder)) return replaceInstUsesWith(I, V); - // (0 - x) & 1 --> x & 1 - Value *X; - if (match(Op1, m_One()) && match(Op0, m_Sub(m_Zero(), m_Value(X)))) - return BinaryOperator::CreateAnd(X, Op1); + if (match(Op1, m_One())) { + Value *X; + // (0 - x) & 1 --> x & 1 + if (match(Op0, m_Sub(m_Zero(), m_Value(X)))) + return BinaryOperator::CreateAnd(X, Op1); + + // (1 << x) & 1 --> zext(x == 0) + // (1 >> x) & 1 --> zext(x == 0) + if (match(Op0, m_OneUse(m_LogicalShift(m_One(), m_Value(X))))) { + Value *IsZero = Builder.CreateICmpEQ(X, ConstantInt::get(I.getType(), 0)); + return new ZExtInst(IsZero, I.getType()); + } + } if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) { const APInt &AndRHSMask = AndRHS->getValue(); @@ -1320,17 +1329,6 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { break; } - - case Instruction::Shl: - case Instruction::LShr: - // (1 << x) & 1 --> zext(x == 0) - // (1 >> x) & 1 --> zext(x == 0) - if (AndRHSMask.isOneValue() && Op0LHS == AndRHS) { - Value *NewICmp = - Builder.CreateICmpEQ(Op0RHS, Constant::getNullValue(I.getType())); - return new ZExtInst(NewICmp, I.getType()); - } - break; } // ((C1 OP zext(X)) & C2) -> zext((C1-X) & C2) if C2 fits in the bitwidth |