diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 36 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 8 |
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; } |

