summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-07-15 17:26:01 +0000
committerSanjay Patel <spatel@rotateright.com>2017-07-15 17:26:01 +0000
commit3437ee27407d9fe27155000930a324d1022b781d (patch)
treeeebf814b61dc67fcbf9ede6a358e19e2dd43d58b /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
parente29b112f493cab1cbf5f9a6ed5e8d1ea26f98176 (diff)
downloadbcm5719-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.cpp28
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
OpenPOWER on IntegriCloud