diff options
author | Evgeny Stupachenko <evstupac@gmail.com> | 2016-04-27 03:04:54 +0000 |
---|---|---|
committer | Evgeny Stupachenko <evstupac@gmail.com> | 2016-04-27 03:04:54 +0000 |
commit | 23ce61b66334b78ce7a0dd48c24fbf407ca12d8b (patch) | |
tree | efea78cc6444d7653d38307f6734f96e4b3f412f /llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | |
parent | c67651dd70b740765cdb809aa0c87236a7eedc1a (diff) | |
download | bcm5719-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.cpp | 19 |
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 |