diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 20 | ||||
-rw-r--r-- | lib/Analysis/LoopInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 42 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 12 | ||||
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 1 |
5 files changed, 52 insertions, 29 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index b4686a1ff1758..8da2f0981d0ca 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1106,6 +1106,16 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const Query &Q, if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, Q, MaxRecurse)) return V; + // udiv %V, C -> 0 if %V < C + if (MaxRecurse) { + if (Constant *C = dyn_cast_or_null<Constant>(SimplifyICmpInst( + ICmpInst::ICMP_ULT, Op0, Op1, Q, MaxRecurse - 1))) { + if (C->isAllOnesValue()) { + return Constant::getNullValue(Op0->getType()); + } + } + } + return nullptr; } @@ -1247,6 +1257,16 @@ static Value *SimplifyURemInst(Value *Op0, Value *Op1, const Query &Q, if (Value *V = SimplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse)) return V; + // urem %V, C -> %V if %V < C + if (MaxRecurse) { + if (Constant *C = dyn_cast_or_null<Constant>(SimplifyICmpInst( + ICmpInst::ICMP_ULT, Op0, Op1, Q, MaxRecurse - 1))) { + if (C->isAllOnesValue()) { + return Op0; + } + } + } + return nullptr; } diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 19c0171740c92..3d85ef6988a9a 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -179,9 +179,9 @@ bool Loop::isLCSSAForm(DominatorTree &DT) const { } bool Loop::isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const { - // For each block we check that it doesn't have any uses outside of it's - // innermost loop. This process will transitivelly guarntee that current loop - // and all of the nested loops are in the LCSSA form. + // For each block we check that it doesn't have any uses outside of its + // innermost loop. This process will transitively guarantee that the current + // loop and all of the nested loops are in LCSSA form. return all_of(this->blocks(), [&](const BasicBlock *BB) { return isBlockInLCSSAForm(*LI.getLoopFor(BB), *BB, DT); }); diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 2746361ab4b58..e7415e6231963 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -344,38 +344,24 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI, if (!InvariantGroupMD) return MemDepResult::getUnknown(); - Value *LoadOperand = LI->getPointerOperand(); + // Take the ptr operand after all casts and geps 0. This way we can search + // cast graph down only. + Value *LoadOperand = LI->getPointerOperand()->stripPointerCasts(); + // It's is not safe to walk the use list of global value, because function // passes aren't allowed to look outside their functions. + // FIXME: this could be fixed by filtering instructions from outside + // of current function. if (isa<GlobalValue>(LoadOperand)) return MemDepResult::getUnknown(); // Queue to process all pointers that are equivalent to load operand. SmallVector<const Value *, 8> LoadOperandsQueue; - SmallSet<const Value *, 14> SeenValues; - auto TryInsertToQueue = [&](Value *V) { - if (SeenValues.insert(V).second) - LoadOperandsQueue.push_back(V); - }; - - TryInsertToQueue(LoadOperand); + LoadOperandsQueue.push_back(LoadOperand); while (!LoadOperandsQueue.empty()) { const Value *Ptr = LoadOperandsQueue.pop_back_val(); - assert(Ptr); - if (isa<GlobalValue>(Ptr)) - continue; - - // Value comes from bitcast: Ptr = bitcast x. Insert x. - if (auto *BCI = dyn_cast<BitCastInst>(Ptr)) - TryInsertToQueue(BCI->getOperand(0)); - // Gep with zeros is equivalent to bitcast. - // FIXME: we are not sure if some bitcast should be canonicalized to gep 0 - // or gep 0 to bitcast because of SROA, so there are 2 forms. When typeless - // pointers will be upstream then both cases will be gone (and this BFS - // also won't be needed). - if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr)) - if (GEP->hasAllZeroIndices()) - TryInsertToQueue(GEP->getOperand(0)); + assert(Ptr && !isa<GlobalValue>(Ptr) && + "Null or GlobalValue should not be inserted"); for (const Use &Us : Ptr->uses()) { auto *U = dyn_cast<Instruction>(Us.getUser()); @@ -385,13 +371,17 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI, // Bitcast or gep with zeros are using Ptr. Add to queue to check it's // users. U = bitcast Ptr if (isa<BitCastInst>(U)) { - TryInsertToQueue(U); + LoadOperandsQueue.push_back(U); continue; } - // U = getelementptr Ptr, 0, 0... + // Gep with zeros is equivalent to bitcast. + // FIXME: we are not sure if some bitcast should be canonicalized to gep 0 + // or gep 0 to bitcast because of SROA, so there are 2 forms. When + // typeless pointers will be ready then both cases will be gone + // (and this BFS also won't be needed). if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) if (GEP->hasAllZeroIndices()) { - TryInsertToQueue(U); + LoadOperandsQueue.push_back(U); continue; } diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 5e566bcdaff4d..44f1a6dde0d21 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -10012,6 +10012,18 @@ void ScalarEvolution::verify() const { // TODO: Verify more things. } +bool ScalarEvolution::invalidate( + Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv) { + // Invalidate the ScalarEvolution object whenever it isn't preserved or one + // of its dependencies is invalidated. + auto PAC = PA.getChecker<ScalarEvolutionAnalysis>(); + return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) || + Inv.invalidate<AssumptionAnalysis>(F, PA) || + Inv.invalidate<DominatorTreeAnalysis>(F, PA) || + Inv.invalidate<LoopAnalysis>(F, PA); +} + AnalysisKey ScalarEvolutionAnalysis::Key; ScalarEvolution ScalarEvolutionAnalysis::run(Function &F, diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 073b4e6ab26ae..d31472c0d33c1 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -3257,6 +3257,7 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V, case Intrinsic::dbg_value: return true; + case Intrinsic::bitreverse: case Intrinsic::bswap: case Intrinsic::ctlz: case Intrinsic::ctpop: |