diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4490,6 +4490,18 @@ } } +/// Determine whether this instruction is either not SCEVable or will always +/// produce a SCEVUnknown. We do not have to walk past such instructions when +/// invalidating. +static bool isAlwaysUnknown(const Instruction *I) { + switch (I->getOpcode()) { + case Instruction::Load: + return true; + default: + return false; + } +} + /// Return an existing SCEV if it exists, otherwise analyze the expression and /// create a new one. const SCEV *ScalarEvolution::getSCEV(Value *V) { @@ -4497,7 +4509,11 @@ if (const SCEV *S = getExistingSCEV(V)) return S; - return createSCEVIter(V); + const SCEV *S = createSCEVIter(V); + assert((!isa(V) || !isAlwaysUnknown(cast(V)) || + isa(S)) && + "isAlwaysUnknown() instruction is not SCEVUnknown"); + return S; } const SCEV *ScalarEvolution::getExistingSCEV(Value *V) { @@ -4798,6 +4814,8 @@ // Push the def-use children onto the Worklist stack. for (User *U : I->users()) { auto *UserInsn = cast(U); + if (isAlwaysUnknown(UserInsn)) + continue; if (Visited.insert(UserInsn).second) Worklist.push_back(UserInsn); }