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 | ca9b7037e28759c200fe5ca98190cabd121a1bba (patch) | |
tree | 87d9cc525f270334d68ab1c057c8cba7b5cc8e81 /lib/Transforms/Scalar/IndVarSimplify.cpp | |
parent | dae9efc23e959d4452f5b67706896ea292b687f3 (diff) | |
download | external_llvm-ca9b7037e28759c200fe5ca98190cabd121a1bba.tar.gz external_llvm-ca9b7037e28759c200fe5ca98190cabd121a1bba.tar.bz2 external_llvm-ca9b7037e28759c200fe5ca98190cabd121a1bba.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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101068 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 4f779050d9..2693f3a9a9 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/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. |