diff options
author | Dan Gohman <gohman@apple.com> | 2010-04-12 21:13:43 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-04-12 21:13:43 +0000 |
commit | 4a645b88ef38178076b7a52d7b2e97abfa1b2d2b (patch) | |
tree | c3957fd9292fc26ce710a2f81af6740f1aec0024 /llvm/lib | |
parent | 933f67887fcce41e73655b33da237e6bc61a46ea (diff) | |
download | bcm5719-llvm-4a645b88ef38178076b7a52d7b2e97abfa1b2d2b.tar.gz bcm5719-llvm-4a645b88ef38178076b7a52d7b2e97abfa1b2d2b.zip |
Suppress LinearFunctionTestReplace when the computed backedge-taken
expression is a UDiv and it doesn't appear that the UDiv came from
the user's source.
ScalarEvolution has recently figured out how to compute a tripcount
expression for the inner loop in
SingleSource/Benchmarks/Shootout/sieve.c, using a udiv. Emitting a
udiv instruction dramatically slows down the enclosing loop.
llvm-svn: 101068
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 4f779050d91..2693f3a9a90 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -134,6 +134,24 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L, BasicBlock *ExitingBlock, BranchInst *BI, SCEVExpander &Rewriter) { + // Special case: If the backedge-taken count is a UDiv, it's very likely a + // UDiv that ScalarEvolution produced in order to compute a precise + // expression, rather than a UDiv from the user's code. If we can't find a + // UDiv in the code with some simple searching, assume the former and forego + // rewriting the loop. + if (isa<SCEVUDivExpr>(BackedgeTakenCount)) { + ICmpInst *OrigCond = dyn_cast<ICmpInst>(BI->getCondition()); + if (!OrigCond) return 0; + const SCEV *R = SE->getSCEV(OrigCond->getOperand(1)); + R = SE->getMinusSCEV(R, SE->getIntegerSCEV(1, R->getType())); + if (R != BackedgeTakenCount) { + const SCEV *L = SE->getSCEV(OrigCond->getOperand(0)); + L = SE->getMinusSCEV(L, SE->getIntegerSCEV(1, L->getType())); + if (L != BackedgeTakenCount) + return 0; + } + } + // If the exiting block is not the same as the backedge block, we must compare // against the preincremented value, otherwise we prefer to compare against // the post-incremented value. |