summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp20
-rw-r--r--lib/Analysis/LoopInfo.cpp6
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp42
-rw-r--r--lib/Analysis/ScalarEvolution.cpp12
-rw-r--r--lib/Analysis/ValueTracking.cpp1
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: