diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 41940e980faa..ba7f367267fe 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Argument.h" @@ -254,15 +255,15 @@ static BinaryOperator *CreateMul(Value *S1, Value *S2, const Twine &Name, } } -static BinaryOperator *CreateNeg(Value *S1, const Twine &Name, - Instruction *InsertBefore, Value *FlagsOp) { +static Instruction *CreateNeg(Value *S1, const Twine &Name, + Instruction *InsertBefore, Value *FlagsOp) { if (S1->getType()->isIntOrIntVectorTy()) return BinaryOperator::CreateNeg(S1, Name, InsertBefore); - else { - BinaryOperator *Res = BinaryOperator::CreateFNeg(S1, Name, InsertBefore); - Res->setFastMathFlags(cast<FPMathOperator>(FlagsOp)->getFastMathFlags()); - return Res; - } + + if (auto *FMFSource = dyn_cast<Instruction>(FlagsOp)) + return UnaryOperator::CreateFNegFMF(S1, FMFSource, Name, InsertBefore); + + return UnaryOperator::CreateFNeg(S1, Name, InsertBefore); } /// Replace 0-X with X*-1. @@ -914,7 +915,7 @@ static Value *NegateValue(Value *V, Instruction *BI, // Insert a 'neg' instruction that subtracts the value from zero to get the // negation. - BinaryOperator *NewNeg = CreateNeg(V, V->getName() + ".neg", BI, BI); + Instruction *NewNeg = CreateNeg(V, V->getName() + ".neg", BI, BI); ToRedo.insert(NewNeg); return NewNeg; } @@ -975,7 +976,8 @@ static BinaryOperator *BreakUpSubtract(Instruction *Sub, /// this into a multiply by a constant to assist with further reassociation. static BinaryOperator *ConvertShiftToMul(Instruction *Shl) { Constant *MulCst = ConstantInt::get(Shl->getType(), 1); - MulCst = ConstantExpr::getShl(MulCst, cast<Constant>(Shl->getOperand(1))); + auto *SA = cast<ConstantInt>(Shl->getOperand(1)); + MulCst = ConstantExpr::getShl(MulCst, SA); BinaryOperator *Mul = BinaryOperator::CreateMul(Shl->getOperand(0), MulCst, "", Shl); @@ -988,10 +990,12 @@ static BinaryOperator *ConvertShiftToMul(Instruction *Shl) { // We can safely preserve the nuw flag in all cases. It's also safe to turn a // nuw nsw shl into a nuw nsw mul. However, nsw in isolation requires special - // handling. + // handling. It can be preserved as long as we're not left shifting by + // bitwidth - 1. bool NSW = cast<BinaryOperator>(Shl)->hasNoSignedWrap(); bool NUW = cast<BinaryOperator>(Shl)->hasNoUnsignedWrap(); - if (NSW && NUW) + unsigned BitWidth = Shl->getType()->getIntegerBitWidth(); + if (NSW && (NUW || SA->getValue().ult(BitWidth - 1))) Mul->setHasNoSignedWrap(true); Mul->setHasNoUnsignedWrap(NUW); return Mul; @@ -1076,7 +1080,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) { const APFloat &F1 = FC1->getValueAPF(); APFloat F2(FC2->getValueAPF()); F2.changeSign(); - if (F1.compare(F2) == APFloat::cmpEqual) { + if (F1 == F2) { FoundFactor = NeedsNegate = true; Factors.erase(Factors.begin() + i); break; @@ -1721,7 +1725,7 @@ static bool collectMultiplyFactors(SmallVectorImpl<ValueEntry> &Ops, } /// Build a tree of multiplies, computing the product of Ops. -static Value *buildMultiplyTree(IRBuilder<> &Builder, +static Value *buildMultiplyTree(IRBuilderBase &Builder, SmallVectorImpl<Value*> &Ops) { if (Ops.size() == 1) return Ops.back(); @@ -1744,7 +1748,7 @@ static Value *buildMultiplyTree(IRBuilder<> &Builder, /// DAG of multiplies to compute the final product, and return that product /// value. Value * -ReassociatePass::buildMinimalMultiplyDAG(IRBuilder<> &Builder, +ReassociatePass::buildMinimalMultiplyDAG(IRBuilderBase &Builder, SmallVectorImpl<Factor> &Factors) { assert(Factors[0].Power); SmallVector<Value *, 4> OuterProduct; @@ -1899,7 +1903,7 @@ void ReassociatePass::RecursivelyEraseDeadInsts(Instruction *I, ValueRankMap.erase(I); Insts.remove(I); RedoInsts.remove(I); - llvm::salvageDebugInfoOrMarkUndef(*I); + llvm::salvageDebugInfo(*I); I->eraseFromParent(); for (auto Op : Ops) if (Instruction *OpInst = dyn_cast<Instruction>(Op)) @@ -1916,7 +1920,7 @@ void ReassociatePass::EraseInst(Instruction *I) { // Erase the dead instruction. ValueRankMap.erase(I); RedoInsts.remove(I); - llvm::salvageDebugInfoOrMarkUndef(*I); + llvm::salvageDebugInfo(*I); I->eraseFromParent(); // Optimize its operands. SmallPtrSet<Instruction *, 8> Visited; // Detect self-referential nodes. @@ -2457,6 +2461,8 @@ PreservedAnalyses ReassociatePass::run(Function &F, FunctionAnalysisManager &) { if (MadeChange) { PreservedAnalyses PA; PA.preserveSet<CFGAnalyses>(); + PA.preserve<AAManager>(); + PA.preserve<BasicAA>(); PA.preserve<GlobalsAA>(); return PA; } @@ -2487,6 +2493,8 @@ namespace { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addPreserved<AAResultsWrapperPass>(); + AU.addPreserved<BasicAAWrapperPass>(); AU.addPreserved<GlobalsAAWrapperPass>(); } }; |