So, while trying to reduce a testcase I realized I can trigger a crash in LICM if I specify a given value of -opt-bisect-limit
(the repro is the one from https://llvm.org/bugs/show_bug.cgi?id=30708)
$ ./opt unopt.ll -opt-bisect-limit=53 -O3 [...] BISECT: running pass (43) Loop Invariant Code Motion on loop │·························· BISECT: running pass (44) Unswitch loops on loop │·························· BISECT: running pass (45) Rotate Loops on loop │·························· BISECT: running pass (46) Loop Invariant Code Motion on loop │·························· BISECT: running pass (47) Unswitch loops on loop │·························· BISECT: running pass (48) Rotate Loops on loop │·························· BISECT: running pass (49) Loop Invariant Code Motion on loop │·························· BISECT: running pass (50) Unswitch loops on loop │·························· BISECT: running pass (51) Rotate Loops on loop │·························· BISECT: running pass (52) Loop Invariant Code Motion on loop │·························· BISECT: running pass (53) Unswitch loops on loop │·························· BISECT: NOT running pass (54) Rotate Loops on loop │·························· BISECT: NOT running pass (55) Loop Invariant Code Motion on loop │·························· BISECT: NOT running pass (56) Unswitch loops on loop │·························· BISECT: NOT running pass (57) Rotate Loops on loop │·························· [...] opt: /home/davide/work/llvm-monorepo/llvm/lib/Transforms/Scalar/LICM.cpp:156: virtual bool {anonymous}::LegacyLICMPass::doFinalization(): Assertion `LICM.getLoopToAliasSetMap().empty() && "Didn't free loop alias sets"' failed.
I do think that the problem here is that if skipLoop(L) is true, we don't call the deleteSimpleAnalysisLoop() hook in the Loop Pass Manager, this leaves some pending elements inside LICM internal data structures -> doFinalization() checks for the map to be empty, and hits the assertion.
This function shouldn't be called here. The pass has already run (or not) by this point, and this call will cause the OptBisect component to increment its counter again and skipLoop() may return true here after having returned false when the current LoopPass was run.