mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
LoopUnrollRuntime: Check for overflow in the trip count calculation.
Fixes PR19823. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211436 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -280,17 +280,17 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
|
|||||||
SCEVExpander Expander(*SE, "loop-unroll");
|
SCEVExpander Expander(*SE, "loop-unroll");
|
||||||
Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(),
|
Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(),
|
||||||
PreHeaderBR);
|
PreHeaderBR);
|
||||||
Type *CountTy = TripCount->getType();
|
|
||||||
BinaryOperator *ModVal =
|
|
||||||
BinaryOperator::CreateURem(TripCount,
|
|
||||||
ConstantInt::get(CountTy, Count),
|
|
||||||
"xtraiter");
|
|
||||||
ModVal->insertBefore(PreHeaderBR);
|
|
||||||
|
|
||||||
// Check if for no extra iterations, then jump to unrolled loop
|
IRBuilder<> B(PreHeaderBR);
|
||||||
Value *BranchVal = new ICmpInst(PreHeaderBR,
|
Value *ModVal = B.CreateAnd(TripCount, Count - 1, "xtraiter");
|
||||||
ICmpInst::ICMP_NE, ModVal,
|
|
||||||
ConstantInt::get(CountTy, 0), "lcmp");
|
// Check if for no extra iterations, then jump to unrolled loop. We have to
|
||||||
|
// check that the trip count computation didn't overflow when adding one to
|
||||||
|
// the backedge taken count.
|
||||||
|
Value *LCmp = B.CreateIsNotNull(ModVal, "lcmp.mod");
|
||||||
|
Value *OverflowCheck = B.CreateIsNull(TripCount, "lcmp.overflow");
|
||||||
|
Value *BranchVal = B.CreateOr(OverflowCheck, LCmp, "lcmp.or");
|
||||||
|
|
||||||
// Branch to either the extra iterations or the unrolled loop
|
// Branch to either the extra iterations or the unrolled loop
|
||||||
// We will fix up the true branch label when adding loop body copies
|
// We will fix up the true branch label when adding loop body copies
|
||||||
BranchInst::Create(PEnd, PEnd, BranchVal, PreHeaderBR);
|
BranchInst::Create(PEnd, PEnd, BranchVal, PreHeaderBR);
|
||||||
@@ -344,6 +344,7 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The comparison w/ the extra iteration value and branch
|
// The comparison w/ the extra iteration value and branch
|
||||||
|
Type *CountTy = TripCount->getType();
|
||||||
Value *BranchVal = new ICmpInst(*NewBB, ICmpInst::ICMP_EQ, ModVal,
|
Value *BranchVal = new ICmpInst(*NewBB, ICmpInst::ICMP_EQ, ModVal,
|
||||||
ConstantInt::get(CountTy, leftOverIters),
|
ConstantInt::get(CountTy, leftOverIters),
|
||||||
"un.tmp");
|
"un.tmp");
|
||||||
|
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
; Tests for unrolling loops with run-time trip counts
|
; Tests for unrolling loops with run-time trip counts
|
||||||
|
|
||||||
|
; CHECK: %xtraiter = and i32 %n
|
||||||
|
; CHECK: %lcmp.mod = icmp ne i32 %xtraiter, 0
|
||||||
|
; CHECK: %lcmp.overflow = icmp eq i32 %n, 0
|
||||||
|
; CHECK: %lcmp.or = or i1 %lcmp.overflow, %lcmp.mod
|
||||||
|
; CHECK: br i1 %lcmp.or, label %unr.cmp
|
||||||
|
|
||||||
; CHECK: unr.cmp{{.*}}:
|
; CHECK: unr.cmp{{.*}}:
|
||||||
; CHECK: for.body.unr{{.*}}:
|
; CHECK: for.body.unr{{.*}}:
|
||||||
; CHECK: for.body:
|
; CHECK: for.body:
|
||||||
|
Reference in New Issue
Block a user