summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2017-07-11 17:16:33 +0000
committerAnna Thomas <anna@azul.com>2017-07-11 17:16:33 +0000
commit5526a33f4fffbe840f19af109f9e9eb35aa20f3b (patch)
tree6e6cb16dcfa03e75377b799444171b056598db57 /llvm/lib
parentf67cd8259d6f50ff342c038966ff39e055e901e1 (diff)
downloadbcm5719-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.cpp12
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)
OpenPOWER on IntegriCloud