summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
diff options
context:
space:
mode:
authorEvgeny Stupachenko <evstupac@gmail.com>2016-04-27 03:04:54 +0000
committerEvgeny Stupachenko <evstupac@gmail.com>2016-04-27 03:04:54 +0000
commit23ce61b66334b78ce7a0dd48c24fbf407ca12d8b (patch)
treeefea78cc6444d7653d38307f6734f96e4b3f412f /llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
parentc67651dd70b740765cdb809aa0c87236a7eedc1a (diff)
downloadbcm5719-llvm-23ce61b66334b78ce7a0dd48c24fbf407ca12d8b.tar.gz
bcm5719-llvm-23ce61b66334b78ce7a0dd48c24fbf407ca12d8b.zip
The patch fixes PR27392.
Summary: It is incorrect to compare TripCount (which is BECount + 1) with extraiters (or Count) to check if we should enter unrolled loop or not, because TripCount can potentially overflow (when BECount is max unsigned integer). While comparing BECount with (Count - 1) is overflow safe and therefore correct. Reviewer: hfinkel Differential Revision: http://reviews.llvm.org/D19256 From: Evgeny Stupachenko <evstupac@gmail.com> llvm-svn: 267662
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp19
1 files changed, 10 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
index da66da0e85f..861a50cf354 100644
--- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
@@ -246,7 +246,7 @@ static void ConnectEpilog(Loop *L, Value *ModVal, BasicBlock *NewExit,
Instruction *InsertPt = NewExit->getTerminator();
IRBuilder<> B(InsertPt);
- Value *BrLoopExit = B.CreateIsNotNull(ModVal);
+ Value *BrLoopExit = B.CreateIsNotNull(ModVal, "lcmp.mod");
assert(Exit && "Loop must have a single exit block only");
// Split the exit to maintain loop canonicalization guarantees
SmallVector<BasicBlock*, 4> Preds(predecessors(Exit));
@@ -416,7 +416,7 @@ static void CloneLoopBlocks(Loop *L, Value *NewIter,
///
/// ***Epilog case***
/// extraiters = tripcount % loopfactor
-/// if (extraiters == tripcount) jump LoopExit:
+/// if (tripcount < loopfactor) jump LoopExit:
/// unroll_iters = tripcount - extraiters
/// Loop: LoopBody; (executes unroll_iter times);
/// unroll_iter -= 1
@@ -575,14 +575,15 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
ConstantInt::get(BECount->getType(), Count),
"xtraiter");
}
- Value *CmpOperand =
- UseEpilogRemainder ? TripCount :
- ConstantInt::get(TripCount->getType(), 0);
- Value *BranchVal = B.CreateICmpNE(ModVal, CmpOperand, "lcmp.mod");
- BasicBlock *FirstLoop = UseEpilogRemainder ? NewPreHeader : PrologPreHeader;
- BasicBlock *SecondLoop = UseEpilogRemainder ? NewExit : PrologExit;
+ Value *BranchVal =
+ UseEpilogRemainder ? B.CreateICmpULT(BECount,
+ ConstantInt::get(BECount->getType(),
+ Count - 1)) :
+ B.CreateIsNotNull(ModVal, "lcmp.mod");
+ BasicBlock *RemainderLoop = UseEpilogRemainder ? NewExit : PrologPreHeader;
+ BasicBlock *UnrollingLoop = UseEpilogRemainder ? NewPreHeader : PrologExit;
// Branch to either remainder (extra iterations) loop or unrolling loop.
- B.CreateCondBr(BranchVal, FirstLoop, SecondLoop);
+ B.CreateCondBr(BranchVal, RemainderLoop, UnrollingLoop);
PreHeaderBR->eraseFromParent();
Function *F = Header->getParent();
// Get an ordered list of blocks in the loop to help with the ordering of the
OpenPOWER on IntegriCloud