[LoopUnroll] Fix dangling pointers in SCEV
authorMax Kazantsev <max.kazantsev@azul.com>
Mon, 26 Mar 2018 11:31:46 +0000 (11:31 +0000)
committerMax Kazantsev <max.kazantsev@azul.com>
Mon, 26 Mar 2018 11:31:46 +0000 (11:31 +0000)
commita55749312b6c2a117d407b085928f606952fa958
treed04052e8a95235977cddcd38e448d5b32d86adb2
parent311b63f13b0873b183f2a7e57eecf0257c7bffa0
[LoopUnroll] Fix dangling pointers in SCEV

Current logic of loop SCEV invalidation in Loop Unroller implicitly relies on
fact that exit count of outer loops cannot rely on exiting blocks of
inner loops, which is true in current implementation of backedge taken count
calculation but is wrong in general. As result, when we only forget the loop that
we have just unrolled, we may still have cached data for its outer loops (in particular,
exit counts) which keeps references on blocks of inner loop that could have been
changed or even deleted.

The attached test demonstrates a situaton when after unrolling of innermost loop
the outermost loop contains a dangling pointer on non-existant block. The problem
shows up when we apply patch https://reviews.llvm.org/D44677 that makes SCEV
smarter about exit count calculation. I am not sure if the bug exists without this patch,
it appears that now it is accidentally correct just because in practice exact backedge
taken count for outer loops with complex control flow inside is never calculated.
But when SCEV learns to do so, this problem shows up.

This patch replaces existing logic of SCEV loop invalidation with a correct one, which
happens to be invalidation of outermost loop (which also leads to invalidation of all
loops inside of it). It is the only way to ensure that no outer loop keeps dangling pointers
on removed blocks, or just outdated information that has changed after unrolling.

Differential Revision: https://reviews.llvm.org/D44818
Reviewed By: samparker

llvm-svn: 328483
llvm/lib/Transforms/Utils/LoopUnroll.cpp
llvm/test/Transforms/LoopUnroll/invalidate_right_loop.ll [new file with mode: 0644]