diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-15 22:30:16 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-15 22:30:16 +0000 |
commit | 9f61947910e6ab40de38e6b4034751ef1513200f (patch) | |
tree | 3231b7529d89052b2edb92bb5ddc6a9e960e5161 /lib/Transforms/Scalar/IndVarSimplify.cpp | |
parent | 5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (diff) |
Notes
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index e83a5c421b47..9cf0ca0912f9 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1623,15 +1623,30 @@ LinearFunctionTestReplace(Loop *L, // compare against the post-incremented value, otherwise we must compare // against the preincremented value. if (L->getExitingBlock() == L->getLoopLatch()) { - // Add one to the "backedge-taken" count to get the trip count. - // This addition may overflow, which is valid as long as the comparison is - // truncated to BackedgeTakenCount->getType(). - IVCount = SE->getAddExpr(BackedgeTakenCount, - SE->getConstant(BackedgeTakenCount->getType(), 1)); // The BackedgeTaken expression contains the number of times that the // backedge branches to the loop header. This is one less than the // number of times the loop executes, so use the incremented indvar. - CmpIndVar = IndVar->getIncomingValueForBlock(L->getExitingBlock()); + llvm::Value *IncrementedIndvar = + IndVar->getIncomingValueForBlock(L->getExitingBlock()); + const auto *IncrementedIndvarSCEV = + cast<SCEVAddRecExpr>(SE->getSCEV(IncrementedIndvar)); + // It is unsafe to use the incremented indvar if it has a wrapping flag, we + // don't want to compare against a poison value. Check the SCEV that + // corresponds to the incremented indvar, the SCEVExpander will only insert + // flags in the IR if the SCEV originally had wrapping flags. + // FIXME: In theory, SCEV could drop flags even though they exist in IR. + // A more robust solution would involve getting a new expression for + // CmpIndVar by applying non-NSW/NUW AddExprs. + if (!ScalarEvolution::maskFlags(IncrementedIndvarSCEV->getNoWrapFlags(), + SCEV::FlagNUW | SCEV::FlagNSW)) { + // Add one to the "backedge-taken" count to get the trip count. + // This addition may overflow, which is valid as long as the comparison is + // truncated to BackedgeTakenCount->getType(). + IVCount = + SE->getAddExpr(BackedgeTakenCount, + SE->getConstant(BackedgeTakenCount->getType(), 1)); + CmpIndVar = IncrementedIndvar; + } } Value *ExitCnt = genLoopLimit(IndVar, IVCount, L, Rewriter, SE); |