diff options
| author | Daniel Neilson <dneilson@azul.com> | 2018-03-05 22:27:30 +0000 |
|---|---|---|
| committer | Daniel Neilson <dneilson@azul.com> | 2018-03-05 22:27:30 +0000 |
| commit | 82daad31fea78a9c75fcbbe79ce7070e642640d0 (patch) | |
| tree | 90cbd7f362b6772caf6724cf0469550860daf08d /llvm/lib | |
| parent | 74ff6ff437a6dd68e38dcbb50fde3f09690364d5 (diff) | |
| download | bcm5719-llvm-82daad31fea78a9c75fcbbe79ce7070e642640d0.tar.gz bcm5719-llvm-82daad31fea78a9c75fcbbe79ce7070e642640d0.zip | |
[RewriteStatepoints] Fix stale parse points
Summary:
RewriteStatepointsForGC collects parse points for further processing.
During the collection if a callsite is found in an unreachable block
(DominatorTree::isReachableFromEntry()) then all unreachable blocks are
removed by removeUnreachableBlocks(). Some of the removed blocks could
have been reachable according to DominatorTree::isReachableFromEntry().
In this case the collected parse points became stale and resulted in a
crash when accessed.
The fix is to unconditionally canonicalize the IR to
removeUnreachableBlocks and then collect the parse points.
The added test crashes with the old version and passes with this patch.
Patch by Yevgeny Rouban!
Reviewed by: Anna
Differential Revision: https://reviews.llvm.org/D43929
llvm-svn: 326748
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index 99073ae527b..43740ae1c5c 100644 --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -2529,30 +2529,31 @@ bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT, return false; }; + + // Delete any unreachable statepoints so that we don't have unrewritten + // statepoints surviving this pass. This makes testing easier and the + // resulting IR less confusing to human readers. + DeferredDominance DD(DT); + bool MadeChange = removeUnreachableBlocks(F, nullptr, &DD); + DD.flush(); + // Gather all the statepoints which need rewritten. Be careful to only // consider those in reachable code since we need to ask dominance queries // when rewriting. We'll delete the unreachable ones in a moment. SmallVector<CallSite, 64> ParsePointNeeded; - bool HasUnreachableStatepoint = false; for (Instruction &I : instructions(F)) { // TODO: only the ones with the flag set! if (NeedsRewrite(I)) { - if (DT.isReachableFromEntry(I.getParent())) - ParsePointNeeded.push_back(CallSite(&I)); - else - HasUnreachableStatepoint = true; + // NOTE removeUnreachableBlocks() is stronger than + // DominatorTree::isReachableFromEntry(). In other words + // removeUnreachableBlocks can remove some blocks for which + // isReachableFromEntry() returns true. + assert(DT.isReachableFromEntry(I.getParent()) && + "no unreachable blocks expected"); + ParsePointNeeded.push_back(CallSite(&I)); } } - bool MadeChange = false; - - // Delete any unreachable statepoints so that we don't have unrewritten - // statepoints surviving this pass. This makes testing easier and the - // resulting IR less confusing to human readers. Rather than be fancy, we - // just reuse a utility function which removes the unreachable blocks. - if (HasUnreachableStatepoint) - MadeChange |= removeUnreachableBlocks(F); - // Return early if no work to do. if (ParsePointNeeded.empty()) return MadeChange; |

