summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-07-21 00:24:18 +0000
committerSanjay Patel <spatel@rotateright.com>2016-07-21 00:24:18 +0000
commit0753c06d9cfd7cbb6af1ed13af073cc274522862 (patch)
treed1979e133c60dda0c86264b1643e6625952f00b8 /llvm/lib/Transforms
parent99bd2de6194551d429751afc77030fdaed4e4dae (diff)
downloadbcm5719-llvm-0753c06d9cfd7cbb6af1ed13af073cc274522862.tar.gz
bcm5719-llvm-0753c06d9cfd7cbb6af1ed13af073cc274522862.zip
[InstCombine] LogicOpc (zext X), C --> zext (LogicOpc X, C) (PR28476)
The benefits of this change include: 1. Remove DeMorgan-matching code that was added specifically to work-around the missing transform in http://reviews.llvm.org/rL248634. 2. Makes the DeMorgan transform work for vectors too. 3. Fix PR28476: https://llvm.org/bugs/show_bug.cgi?id=28476 Extending this transform to other casts and other associative operators may be useful too. See https://reviews.llvm.org/D22421 for a prerequisite for doing that though. Differential Revision: https://reviews.llvm.org/D22271 llvm-svn: 276221
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp36
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp8
2 files changed, 16 insertions, 28 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 4314b2b0a37..3871b8ab636 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1123,26 +1123,6 @@ static Instruction *matchDeMorgansLaws(BinaryOperator &I,
return BinaryOperator::CreateNot(LogicOp);
}
- // De Morgan's Law in disguise:
- // (zext(bool A) ^ 1) & (zext(bool B) ^ 1) -> zext(~(A | B))
- // (zext(bool A) ^ 1) | (zext(bool B) ^ 1) -> zext(~(A & B))
- Value *A = nullptr;
- Value *B = nullptr;
- ConstantInt *C1 = nullptr;
- if (match(Op0, m_OneUse(m_Xor(m_ZExt(m_Value(A)), m_ConstantInt(C1)))) &&
- match(Op1, m_OneUse(m_Xor(m_ZExt(m_Value(B)), m_Specific(C1))))) {
- // TODO: This check could be loosened to handle different type sizes.
- // Alternatively, we could fix the definition of m_Not to recognize a not
- // operation hidden by a zext?
- if (A->getType()->isIntegerTy(1) && B->getType()->isIntegerTy(1) &&
- C1->isOne()) {
- Value *LogicOp = Builder->CreateBinOp(Opcode, A, B,
- I.getName() + ".demorgan");
- Value *Not = Builder->CreateNot(LogicOp);
- return CastInst::CreateZExtOrBitCast(Not, I.getType());
- }
- }
-
return nullptr;
}
@@ -1199,6 +1179,22 @@ Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) {
return CastInst::CreateBitOrPointerCast(NewOp, DestTy);
}
+ // Similarly, if one operand is zexted and the other is a constant, move the
+ // logic operation ahead of the zext if the constant is unchanged in the
+ // smaller source type. Performing the logic in a smaller type may provide
+ // more information to later folds, and the smaller logic instruction may be
+ // cheaper (particularly in the case of vectors).
+ Value *X;
+ if (match(Op0, m_OneUse(m_ZExt(m_Value(X)))) && match(Op1, m_Constant(C))) {
+ Constant *TruncC = ConstantExpr::getTrunc(C, SrcTy);
+ Constant *ZextTruncC = ConstantExpr::getZExt(TruncC, DestTy);
+ if (ZextTruncC == C) {
+ // LogicOpc (zext X), C --> zext (LogicOpc X, C)
+ Value *NewOp = Builder->CreateBinOp(LogicOpc, X, TruncC);
+ return new ZExtInst(NewOp, DestTy);
+ }
+ }
+
CastInst *Cast1 = dyn_cast<CastInst>(Op1);
if (!Cast1)
return nullptr;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 8f3b8badcdf..0d79733aae9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -920,14 +920,6 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
return BinaryOperator::CreateXor(Builder->CreateAnd(X, ZC), ZC);
}
- // zext (xor i1 X, true) to i32 --> xor (zext i1 X to i32), 1
- if (SrcI && SrcI->hasOneUse() &&
- SrcI->getType()->getScalarType()->isIntegerTy(1) &&
- match(SrcI, m_Not(m_Value(X))) && (!X->hasOneUse() || !isa<CmpInst>(X))) {
- Value *New = Builder->CreateZExt(X, CI.getType());
- return BinaryOperator::CreateXor(New, ConstantInt::get(CI.getType(), 1));
- }
-
return nullptr;
}
OpenPOWER on IntegriCloud