diff options
author | Anna Thomas <anna@azul.com> | 2017-07-11 17:16:33 +0000 |
---|---|---|
committer | Anna Thomas <anna@azul.com> | 2017-07-11 17:16:33 +0000 |
commit | 5526a33f4fffbe840f19af109f9e9eb35aa20f3b (patch) | |
tree | 6e6cb16dcfa03e75377b799444171b056598db57 /llvm/lib | |
parent | f67cd8259d6f50ff342c038966ff39e055e901e1 (diff) | |
download | bcm5719-llvm-5526a33f4fffbe840f19af109f9e9eb35aa20f3b.tar.gz bcm5719-llvm-5526a33f4fffbe840f19af109f9e9eb35aa20f3b.zip |
[LoopUnrollRuntime] Avoid multi-exit nested loop with epilog generation
The loop structure for the outer loop does not contain the epilog
preheader when we try to unroll inner loop with multiple exits and
epilog code is generated. For now, we just bail out in such cases.
Added a test case that shows the problem. Without this bailout, we would
trip on assert saying LCSSA form is incorrect for outer loop.
llvm-svn: 307676
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 59408ffe7a7..2b432426b24 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -470,8 +470,9 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count, bool UseEpilogRemainder, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, bool PreserveLCSSA) { - // for now, only unroll loops that contain a single exit - if (!UnrollRuntimeMultiExit && !L->getExitingBlock()) + bool hasMultipleExitingBlocks = !L->getExitingBlock(); + // Support only single exiting block unless UnrollRuntimeMultiExit is true. + if (!UnrollRuntimeMultiExit && hasMultipleExitingBlocks) return false; // Make sure the loop is in canonical form. @@ -516,6 +517,13 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count, // connectEpilog. if (!LatchExit->getSinglePredecessor()) return false; + // FIXME: We bail out of multi-exit unrolling when epilog loop is generated + // and L is an inner loop. This is because in presence of multiple exits, the + // outer loop is incorrect: we do not add the EpilogPreheader and exit to the + // outer loop. This is automatically handled in the prolog case, so we do not + // have that bug in prolog generation. + if (hasMultipleExitingBlocks && UseEpilogRemainder && L->getParentLoop()) + return false; // Use Scalar Evolution to compute the trip count. This allows more loops to // be unrolled than relying on induction var simplification. if (!SE) |