Author: Roman Lebedev Date: 2020-12-24T21:20:47+03:00 New Revision: b3021a72a6d2fea8702b75f34f9f3317ae923d92
URL: https://github.com/llvm/llvm-project/commit/b3021a72a6d2fea8702b75f34f9f3317ae923d92 DIFF: https://github.com/llvm/llvm-project/commit/b3021a72a6d2fea8702b75f34f9f3317ae923d92.diff LOG: [IR][InstCombine] Add m_ImmConstant(), that matches on non-ConstantExpr constants, and use it A pattern to ignore ConstantExpr's is quite common, since they frequently lead into infinite combine loops, so let's make writing it easier. Added: Modified: llvm/include/llvm/IR/PatternMatch.h llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index c25573b9f8a6..c40f5d1d15d1 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -88,11 +88,6 @@ inline class_match<BinaryOperator> m_BinOp() { /// Matches any compare instruction and ignore it. inline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); } -/// Match an arbitrary ConstantInt and ignore it. -inline class_match<ConstantInt> m_ConstantInt() { - return class_match<ConstantInt>(); -} - /// Match an arbitrary undef constant. inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } @@ -102,6 +97,21 @@ inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); /// Match an arbitrary Constant and ignore it. inline class_match<Constant> m_Constant() { return class_match<Constant>(); } +/// Match an arbitrary ConstantInt and ignore it. +inline class_match<ConstantInt> m_ConstantInt() { + return class_match<ConstantInt>(); +} + +/// Match an arbitrary ConstantFP and ignore it. +inline class_match<ConstantFP> m_ConstantFP() { + return class_match<ConstantFP>(); +} + +/// Match an arbitrary ConstantExpr and ignore it. +inline class_match<ConstantExpr> m_ConstantExpr() { + return class_match<ConstantExpr>(); +} + /// Match an arbitrary basic block value and ignore it. inline class_match<BasicBlock> m_BasicBlock() { return class_match<BasicBlock>(); @@ -699,21 +709,38 @@ inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; } /// Match a with overflow intrinsic, capturing it if we match. inline bind_ty<WithOverflowInst> m_WithOverflowInst(WithOverflowInst *&I) { return I; } -/// Match a ConstantInt, capturing the value if we match. -inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } - /// Match a Constant, capturing the value if we match. inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } +/// Match a ConstantInt, capturing the value if we match. +inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } + /// Match a ConstantFP, capturing the value if we match. inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } +/// Match a ConstantExpr, capturing the value if we match. +inline bind_ty<ConstantExpr> m_ConstantExpr(ConstantExpr *&C) { return C; } + /// Match a basic block value, capturing it if we match. inline bind_ty<BasicBlock> m_BasicBlock(BasicBlock *&V) { return V; } inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) { return V; } +/// Match an arbitrary immediate Constant and ignore it. +inline match_combine_and<class_match<Constant>, + match_unless<class_match<ConstantExpr>>> +m_ImmConstant() { + return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr())); +} + +/// Match an immediate Constant, capturing the value if we match. +inline match_combine_and<bind_ty<Constant>, + match_unless<class_match<ConstantExpr>>> +m_ImmConstant(Constant *&C) { + return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr())); +} + /// Match a specified Value*. struct specificval_ty { const Value *Val; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 74ba23d343a0..c20861f20f07 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1841,7 +1841,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { Constant *C2; // C-(C2-X) --> X+(C-C2) - if (match(Op1, m_Sub(m_Constant(C2), m_Value(X))) && !isa<ConstantExpr>(C2)) + if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X)))) return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2)); } @@ -2198,7 +2198,7 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) { // X - C --> X + (-C) // But don't transform constant expressions because there's an inverse fold // for X + (-Y) --> X - Y. - if (match(Op1, m_Constant(C)) && !isa<ConstantExpr>(Op1)) + if (match(Op1, m_ImmConstant(C))) return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); // X - (-Y) --> X + Y diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 22e4fd7d9955..3dc8508aa760 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -883,8 +883,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { Type *Ty = II->getType(); unsigned BitWidth = Ty->getScalarSizeInBits(); Constant *ShAmtC; - if (match(II->getArgOperand(2), m_Constant(ShAmtC)) && - !isa<ConstantExpr>(ShAmtC) && !ShAmtC->containsConstantExpression()) { + if (match(II->getArgOperand(2), m_ImmConstant(ShAmtC)) && + !ShAmtC->containsConstantExpression()) { // Canonicalize a shift amount constant operand to modulo the bit-width. Constant *WidthC = ConstantInt::get(Ty, BitWidth); Constant *ModuloC = ConstantExpr::getURem(ShAmtC, WidthC); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp index 5a72547ce519..494c58e706e1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp @@ -220,8 +220,7 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) { } if (I->getOpcode() == Instruction::Sub && - (I->hasOneUse() || (isa<Constant>(I->getOperand(0)) && - !isa<ConstantExpr>(I->getOperand(0))))) { + (I->hasOneUse() || match(I->getOperand(0), m_ImmConstant()))) { // `sub` is always negatible. // However, only do this either if the old `sub` doesn't stick around, or // it was subtracting from a constant. Otherwise, this isn't profitable. diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index ec932aaf0b9e..5d8abe14327b 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1056,7 +1056,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) { for (unsigned i = 0; i != NumPHIValues; ++i) { Value *InVal = PN->getIncomingValue(i); // If I is a freeze instruction, count undef as a non-constant. - if (isa<Constant>(InVal) && !isa<ConstantExpr>(InVal) && + if (match(InVal, m_ImmConstant()) && (!isa<FreezeInst>(I) || isGuaranteedNotToBeUndefOrPoison(InVal))) continue; @@ -1118,7 +1118,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) { // FalseVInPred versus TrueVInPred. When we have individual nonzero // elements in the vector, we will incorrectly fold InC to // `TrueVInPred`. - if (InC && !isa<ConstantExpr>(InC) && isa<ConstantInt>(InC)) + if (InC && isa<ConstantInt>(InC)) InV = InC->isNullValue() ? FalseVInPred : TrueVInPred; else { // Generate the select in the same block as PN's current incoming block. @@ -1608,8 +1608,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) { if (InstVTy && match(&Inst, m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))), - m_Constant(C))) && - !isa<ConstantExpr>(C) && + m_ImmConstant(C))) && cast<FixedVectorType>(V1->getType())->getNumElements() <= InstVTy->getNumElements()) { assert(InstVTy->getScalarType() == V1->getType()->getScalarType() && _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits