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 @@ -13355,6 +13355,24 @@ SmallPtrSet ReachableBlocks; getReachableBlocks(ReachableBlocks, F); + auto GetDelta = [&](const SCEV *Old, const SCEV *New) -> const SCEV * { + if (containsUndefs(Old) || containsUndefs(New)) { + // SCEV treats "undef" as an unknown but consistent value (i.e. it does + // not propagate undef aggressively). This means we can (and do) fail + // verification in cases where a transform makes a value go from "undef" + // to "undef+1" (say). The transform is fine, since in both cases the + // result is "undef", but SCEV thinks the value increased by 1. + return nullptr; + } + + // Unless VerifySCEVStrict is set, we only compare constant deltas. + const SCEV *Delta = SE2.getMinusSCEV(Old, New); + if (!VerifySCEVStrict && !isa(Delta)) + return nullptr; + + return Delta; + }; + while (!LoopStack.empty()) { auto *L = LoopStack.pop_back_val(); llvm::append_range(LoopStack, *L); @@ -13384,16 +13402,6 @@ continue; } - if (containsUndefs(CurBECount) || containsUndefs(NewBECount)) { - // SCEV treats "undef" as an unknown but consistent value (i.e. it does - // not propagate undef aggressively). This means we can (and do) fail - // verification in cases where a transform makes the trip count of a loop - // go from "undef" to "undef+1" (say). The transform is fine, since in - // both cases the loop iterates "undef" times, but SCEV thinks we - // increased the trip count of the loop by 1 incorrectly. - continue; - } - if (SE.getTypeSizeInBits(CurBECount->getType()) > SE.getTypeSizeInBits(NewBECount->getType())) NewBECount = SE2.getZeroExtendExpr(NewBECount, CurBECount->getType()); @@ -13401,10 +13409,8 @@ SE.getTypeSizeInBits(NewBECount->getType())) CurBECount = SE2.getZeroExtendExpr(CurBECount, NewBECount->getType()); - const SCEV *Delta = SE2.getMinusSCEV(CurBECount, NewBECount); - - // Unless VerifySCEVStrict is set, we only compare constant deltas. - if ((VerifySCEVStrict || isa(Delta)) && !Delta->isZero()) { + const SCEV *Delta = GetDelta(CurBECount, NewBECount); + if (Delta && !Delta->isZero()) { dbgs() << "Trip Count for " << *L << " Changed!\n"; dbgs() << "Old: " << *CurBECount << "\n"; dbgs() << "New: " << *NewBECount << "\n"; @@ -13437,6 +13443,21 @@ << " is in ValueExprMap but not in ExprValueMap\n"; std::abort(); } + + if (auto *I = dyn_cast(&*KV.first)) { + if (!ReachableBlocks.contains(I->getParent())) + continue; + const SCEV *OldSCEV = SCM.visit(KV.second); + const SCEV *NewSCEV = SE2.getSCEV(I); + const SCEV *Delta = GetDelta(OldSCEV, NewSCEV); + if (Delta && !Delta->isZero()) { + dbgs() << "SCEV for value " << *I << " changed!\n" + << "Old: " << *OldSCEV << "\n" + << "New: " << *NewSCEV << "\n" + << "Delta: " << *Delta << "\n"; + std::abort(); + } + } } for (const auto &KV : ExprValueMap) {