Index: llvm/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolution.h +++ llvm/include/llvm/Analysis/ScalarEvolution.h @@ -899,13 +899,6 @@ /// def-use chain linking it to a loop. void forgetValue(Value *V); - /// Called when the client has changed the disposition of values in - /// this loop. - /// - /// We don't have a way to invalidate per-loop dispositions. Clear and - /// recompute is simpler. - void forgetLoopDispositions(const Loop *L); - /// Determine the minimum number of zero bits that S is guaranteed to end in /// (at every loop iteration). It is, at the same time, the minimum number /// of times S is divisible by 2. For example, given {4,+,8} it returns 2. @@ -1631,6 +1624,18 @@ /// an arbitrary expression as opposed to only constants. const SCEV *computeSymbolicMaxBackedgeTakenCount(const Loop *L); + /// Called when the the disposition of values in some loop might changed. + /// + /// We don't have a way to invalidate per-loop dispositions. Clear and + /// recompute is simpler. + void forgetLoopDispositions(); + + /// Called when the the disposition of values in some loop might changed. + /// + /// We don't have a way to invalidate per-block dispositions. Clear and + /// recompute is simpler. + void forgetBlockDispositions(); + // Helper functions for computeExitLimitFromCond to avoid exponential time // complexity. Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -7504,6 +7504,10 @@ // ValuesAtScopes map. LoopWorklist.append(CurrL->begin(), CurrL->end()); } + + // Drop disposition dependencies on forgotten loop and its blocks. + forgetLoopDispositions(); + forgetBlockDispositions(); } void ScalarEvolution::forgetTopmostLoop(const Loop *L) { @@ -7537,12 +7541,17 @@ PushDefUseChildren(I, Worklist); } -} -void ScalarEvolution::forgetLoopDispositions(const Loop *L) { - LoopDispositions.clear(); + // We don't know what SCEVs may depend on this value's disposition, so drop + // all of them. + forgetLoopDispositions(); + forgetBlockDispositions(); } +void ScalarEvolution::forgetLoopDispositions() { LoopDispositions.clear(); } + +void ScalarEvolution::forgetBlockDispositions() { BlockDispositions.clear(); } + /// Get the exact loop backedge taken count considering all loop exits. A /// computable result can only be returned for loops with all exiting blocks /// dominating the latch. howFarToZero assumes that the limit of each loop test Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -495,7 +495,7 @@ MSSA->verifyMemorySSA(); if (Changed && SE) - SE->forgetLoopDispositions(L); + SE->forgetLoop(L); return Changed; } Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopDeletion.cpp +++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp @@ -96,7 +96,7 @@ } if (Changed) - SE.forgetLoopDispositions(L); + SE.forgetLoop(L); if (!AllEntriesInvariant || !AllOutgoingValuesSame) return false; Index: llvm/lib/Transforms/Scalar/LoopSink.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopSink.cpp +++ llvm/lib/Transforms/Scalar/LoopSink.cpp @@ -337,7 +337,7 @@ } if (Changed && SE) - SE->forgetLoopDispositions(&L); + SE->forgetLoop(&L); return Changed; } Index: llvm/lib/Transforms/Utils/LoopSimplify.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopSimplify.cpp +++ llvm/lib/Transforms/Utils/LoopSimplify.cpp @@ -665,7 +665,7 @@ // The loop disposition of all SCEV expressions that depend on any // hoisted values have also changed. if (SE) - SE->forgetLoopDispositions(L); + SE->forgetLoop(L); } if (!AllInvariant) continue; Index: llvm/test/Transforms/LCSSA/pr44058.ll =================================================================== --- llvm/test/Transforms/LCSSA/pr44058.ll +++ llvm/test/Transforms/LCSSA/pr44058.ll @@ -3,10 +3,6 @@ ; The first SCEV verification is required because it queries SCEV and populates ; SCEV caches. Second SCEV verification checks if the caches are in valid state. -; FIXME: breaks due to SCEV verification failure. Cached deleted values. -; REQUIRES: asserts -; XFAIL: * - ; Check that the second SCEV verification doesn't fail. define void @foo(i32* %arg, i32* %arg1, i1 %arg2) { bb: Index: llvm/test/Transforms/LCSSA/pr44320.ll =================================================================== --- llvm/test/Transforms/LCSSA/pr44320.ll +++ llvm/test/Transforms/LCSSA/pr44320.ll @@ -3,10 +3,6 @@ ; The first SCEV verification is required because it queries SCEV and populates ; SCEV caches. Second SCEV verification checks if the caches are in valid state. -; FIXME: breaks due to SCEV verification failure. Cached deleted values. -; REQUIRES: asserts -; XFAIL: * - ; Check that the second SCEV verification doesn't fail. define void @test(i32* %arg, i32* %arg1, i1 %arg2, i1 %arg3) { bb: Index: llvm/test/Transforms/LoopFusion/triple_loop_nest_inner_guard.ll =================================================================== --- llvm/test/Transforms/LoopFusion/triple_loop_nest_inner_guard.ll +++ llvm/test/Transforms/LoopFusion/triple_loop_nest_inner_guard.ll @@ -1,9 +1,5 @@ ; RUN: opt -S -loop-fusion < %s 2>&1 | FileCheck %s -; FIXME: breaks due to SCEV verification failure. Cached deleted values. -; REQUIRES: asserts -; XFAIL: * - ; Verify that LoopFusion can fuse two triple-loop nests with guarded inner ; loops. Loops are in canonical form.