summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-07-15 23:38:13 +0000
committerDan Gohman <gohman@apple.com>2010-07-15 23:38:13 +0000
commitfbbdfcaea78dd354cad7bbf2d98de6d201307c69 (patch)
tree6223bc08075ad6097229c1d4696eef2b41245c6b /llvm/lib/Analysis/ScalarEvolutionExpander.cpp
parent973dc3b1d8f81389ed87664772595afd75567dd3 (diff)
downloadbcm5719-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.cpp16
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.
OpenPOWER on IntegriCloud