diff options
author | Dan Gohman <gohman@apple.com> | 2010-07-15 23:38:13 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-07-15 23:38:13 +0000 |
commit | fbbdfcaea78dd354cad7bbf2d98de6d201307c69 (patch) | |
tree | 6223bc08075ad6097229c1d4696eef2b41245c6b /llvm/lib/Analysis/ScalarEvolutionExpander.cpp | |
parent | 973dc3b1d8f81389ed87664772595afd75567dd3 (diff) | |
download | bcm5719-llvm-fbbdfcaea78dd354cad7bbf2d98de6d201307c69.tar.gz bcm5719-llvm-fbbdfcaea78dd354cad7bbf2d98de6d201307c69.zip |
Fix the order that SCEVExpander considers add operands in so that
it doesn't miss an opportunity to form a GEP, regardless of the
relative loop depths of the operands. This fixes rdar://8197217.
llvm-svn: 108475
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index d4a4b26e25e..0f3e33fe531 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -647,6 +647,11 @@ public: bool operator()(std::pair<const Loop *, const SCEV *> LHS, std::pair<const Loop *, const SCEV *> RHS) const { + // Keep pointer operands sorted at the end. + if (LHS.second->getType()->isPointerTy() != + RHS.second->getType()->isPointerTy()) + return LHS.second->getType()->isPointerTy(); + // Compare loops with PickMostRelevantLoop. if (LHS.first != RHS.first) return PickMostRelevantLoop(LHS.first, RHS.first, DT) != LHS.first; @@ -699,8 +704,15 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { // The running sum expression is a pointer. Try to form a getelementptr // at this level with that as the base. SmallVector<const SCEV *, 4> NewOps; - for (; I != E && I->first == CurLoop; ++I) - NewOps.push_back(I->second); + for (; I != E && I->first == CurLoop; ++I) { + // If the operand is SCEVUnknown and not instructions, peek through + // it, to enable more of it to be folded into the GEP. + const SCEV *X = I->second; + if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(X)) + if (!isa<Instruction>(U->getValue())) + X = SE.getSCEV(U->getValue()); + NewOps.push_back(X); + } Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum); } else if (const PointerType *PTy = dyn_cast<PointerType>(Op->getType())) { // The running sum is an integer, and there's a pointer at this level. |