diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp index 40c84e249523..818c7b40d489 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -466,7 +466,8 @@ using RepeatedValue = std::pair<Value*, APInt>; /// type and thus make the expression bigger. static bool LinearizeExprTree(Instruction *I, SmallVectorImpl<RepeatedValue> &Ops, - ReassociatePass::OrderedSet &ToRedo) { + ReassociatePass::OrderedSet &ToRedo, + bool &HasNUW) { assert((isa<UnaryOperator>(I) || isa<BinaryOperator>(I)) && "Expected a UnaryOperator or BinaryOperator!"); LLVM_DEBUG(dbgs() << "LINEARIZE: " << *I << '\n'); @@ -515,6 +516,9 @@ static bool LinearizeExprTree(Instruction *I, std::pair<Instruction*, APInt> P = Worklist.pop_back_val(); I = P.first; // We examine the operands of this binary operator. + if (isa<OverflowingBinaryOperator>(I)) + HasNUW &= I->hasNoUnsignedWrap(); + for (unsigned OpIdx = 0; OpIdx < I->getNumOperands(); ++OpIdx) { // Visit operands. Value *Op = I->getOperand(OpIdx); APInt Weight = P.second; // Number of paths to this operand. @@ -657,7 +661,8 @@ static bool LinearizeExprTree(Instruction *I, /// Now that the operands for this expression tree are /// linearized and optimized, emit them in-order. void ReassociatePass::RewriteExprTree(BinaryOperator *I, - SmallVectorImpl<ValueEntry> &Ops) { + SmallVectorImpl<ValueEntry> &Ops, + bool HasNUW) { assert(Ops.size() > 1 && "Single values should be used directly!"); // Since our optimizations should never increase the number of operations, the @@ -814,14 +819,20 @@ void ReassociatePass::RewriteExprTree(BinaryOperator *I, if (ExpressionChangedStart) { bool ClearFlags = true; do { - // Preserve FastMathFlags. + // Preserve flags. if (ClearFlags) { if (isa<FPMathOperator>(I)) { FastMathFlags Flags = I->getFastMathFlags(); ExpressionChangedStart->clearSubclassOptionalData(); ExpressionChangedStart->setFastMathFlags(Flags); - } else + } else { ExpressionChangedStart->clearSubclassOptionalData(); + // Note that it doesn't hold for mul if one of the operands is zero. + // TODO: We can preserve NUW flag if we prove that all mul operands + // are non-zero. + if (HasNUW && ExpressionChangedStart->getOpcode() == Instruction::Add) + ExpressionChangedStart->setHasNoUnsignedWrap(); + } } if (ExpressionChangedStart == ExpressionChangedEnd) @@ -921,16 +932,20 @@ static Value *NegateValue(Value *V, Instruction *BI, TheNeg->getParent()->getParent() != BI->getParent()->getParent()) continue; - Instruction *InsertPt; + BasicBlock::iterator InsertPt; if (Instruction *InstInput = dyn_cast<Instruction>(V)) { - InsertPt = InstInput->getInsertionPointAfterDef(); - if (!InsertPt) + auto InsertPtOpt = InstInput->getInsertionPointAfterDef(); + if (!InsertPtOpt) continue; + InsertPt = *InsertPtOpt; } else { - InsertPt = &*TheNeg->getFunction()->getEntryBlock().begin(); + InsertPt = TheNeg->getFunction() + ->getEntryBlock() + .getFirstNonPHIOrDbg() + ->getIterator(); } - TheNeg->moveBefore(InsertPt); + TheNeg->moveBefore(*InsertPt->getParent(), InsertPt); if (TheNeg->getOpcode() == Instruction::Sub) { TheNeg->setHasNoUnsignedWrap(false); TheNeg->setHasNoSignedWrap(false); @@ -1171,7 +1186,8 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) { return nullptr; SmallVector<RepeatedValue, 8> Tree; - MadeChange |= LinearizeExprTree(BO, Tree, RedoInsts); + bool HasNUW = true; + MadeChange |= LinearizeExprTree(BO, Tree, RedoInsts, HasNUW); SmallVector<ValueEntry, 8> Factors; Factors.reserve(Tree.size()); for (unsigned i = 0, e = Tree.size(); i != e; ++i) { @@ -1213,7 +1229,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) { if (!FoundFactor) { // Make sure to restore the operands to the expression tree. - RewriteExprTree(BO, Factors); + RewriteExprTree(BO, Factors, HasNUW); return nullptr; } @@ -1225,7 +1241,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) { RedoInsts.insert(BO); V = Factors[0].Op; } else { - RewriteExprTree(BO, Factors); + RewriteExprTree(BO, Factors, HasNUW); V = BO; } @@ -2252,9 +2268,10 @@ void ReassociatePass::OptimizeInst(Instruction *I) { // with no common bits set, convert it to X+Y. if (I->getOpcode() == Instruction::Or && shouldConvertOrWithNoCommonBitsToAdd(I) && !isLoadCombineCandidate(I) && - haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1), - I->getModule()->getDataLayout(), /*AC=*/nullptr, I, - /*DT=*/nullptr)) { + (cast<PossiblyDisjointInst>(I)->isDisjoint() || + haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1), + SimplifyQuery(I->getModule()->getDataLayout(), + /*DT=*/nullptr, /*AC=*/nullptr, I)))) { Instruction *NI = convertOrWithNoCommonBitsToAdd(I); RedoInsts.insert(I); MadeChange = true; @@ -2349,7 +2366,8 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) { // First, walk the expression tree, linearizing the tree, collecting the // operand information. SmallVector<RepeatedValue, 8> Tree; - MadeChange |= LinearizeExprTree(I, Tree, RedoInsts); + bool HasNUW = true; + MadeChange |= LinearizeExprTree(I, Tree, RedoInsts, HasNUW); SmallVector<ValueEntry, 8> Ops; Ops.reserve(Tree.size()); for (const RepeatedValue &E : Tree) @@ -2542,7 +2560,7 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) { dbgs() << '\n'); // Now that we ordered and optimized the expressions, splat them back into // the expression tree, removing any unneeded nodes. - RewriteExprTree(I, Ops); + RewriteExprTree(I, Ops, HasNUW); } void @@ -2550,7 +2568,7 @@ ReassociatePass::BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT) { // Make a "pairmap" of how often each operand pair occurs. for (BasicBlock *BI : RPOT) { for (Instruction &I : *BI) { - if (!I.isAssociative()) + if (!I.isAssociative() || !I.isBinaryOp()) continue; // Ignore nodes that aren't at the root of trees. |