diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index c3c7c2c2f1f93..9429b2f11a582 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4490,6 +4490,18 @@ void ScalarEvolution::insertValueToMap(Value *V, const SCEV *S) { } } +/// 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 @@ const SCEV *ScalarEvolution::getSCEV(Value *V) { 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 @@ static void PushDefUseChildren(Instruction *I, // 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); }