}
}
+/// 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) {
if (const SCEV *S = getExistingSCEV(V))
return S;
- return createSCEVIter(V);
+ const SCEV *S = createSCEVIter(V);
+ assert((!isa<Instruction>(V) || !isAlwaysUnknown(cast<Instruction>(V)) ||
+ isa<SCEVUnknown>(S)) &&
+ "isAlwaysUnknown() instruction is not SCEVUnknown");
+ return S;
}
const SCEV *ScalarEvolution::getExistingSCEV(Value *V) {
// Push the def-use children onto the Worklist stack.
for (User *U : I->users()) {
auto *UserInsn = cast<Instruction>(U);
+ if (isAlwaysUnknown(UserInsn))
+ continue;
if (Visited.insert(UserInsn).second)
Worklist.push_back(UserInsn);
}