Currently, LoopDeletion refuses to remove dead loops with no exit blocks
because it cannot statically determine the control flow after it removes
the block. This leads to miscompiles if the loop is an infinite loop and
should've been removed.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/include/llvm/Analysis/LoopInfoImpl.h | ||
---|---|---|
146 | I'd put this directly after getExitBlocks(), |
Logic is sound to me. Some nits below.
Please add a test in which an endless loop w/o exits and w/o side-effects can be replaced with unreachable but the loop has more instructions. So, a phi and some control flow that computes the new phi value.
llvm/include/llvm/Analysis/LoopInfoImpl.h | ||
---|---|---|
150 | Nit: size==0 => empty | |
llvm/lib/Transforms/Utils/LoopUtils.cpp | ||
587 | Can't you move ExitBlock into the else branch. Or branch on ExitBlock and assert hasNoExitBlocks if it is null? Also, do we need to do all the stuff below in the endless case? Could we just return from the then branch? Nit: Not sure why you need to set the insert point again. |
- Adds test.
- Uses getExitBlocks() instead of getUniqueExitBlocks() and moved definition.
- Changed definition of hasNoExitBlocks() to use empty() instead of conditional
- Style changes in deleteDeadLoop for readibility.
LGTM, a few nits to be addressed prior to the merge.
llvm/include/llvm/Analysis/LoopInfoImpl.h | ||
---|---|---|
75 | -Unique | |
llvm/lib/Transforms/Scalar/LoopDeletion.cpp | ||
200 | Nit: aka, at most one exit block ;) | |
llvm/lib/Transforms/Utils/LoopUtils.cpp | ||
685 | Assuming the only use of the DeadDebugInst vector is the code blow that we don't execute (no point to "move" the stuff to), this entire loop is useless for the no-exit case. Line 668 is trivially true for the no-exit case and 677-684 not needed as described above. Thus, move the if(ExitBlock) to 648. |
-Unique