summaryrefslogtreecommitdiff
path: root/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
commitbb5d92741b2835eff25e4524bc6a5b0fb4fda855 (patch)
treed8f7a04a866ce14c5e266bc3285a65dd805b144a /lib/Analysis/ScalarEvolutionExpander.cpp
parente9bf7e692e56656ef13b33af86624d0fdcd578fb (diff)
downloadllvm-bb5d92741b2835eff25e4524bc6a5b0fb4fda855.tar.gz
llvm-bb5d92741b2835eff25e4524bc6a5b0fb4fda855.tar.bz2
llvm-bb5d92741b2835eff25e4524bc6a5b0fb4fda855.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108475 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index d4a4b26e25..0f3e33fe53 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/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.