aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-26 16:11:57 +0000
committerDan Gohman <gohman@apple.com>2009-09-26 16:11:57 +0000
commitc70c37794fbff2c615d4f9dc3b6adf9583b855dc (patch)
tree985e38013dcf7bdf938042fdefec440e5c4e6e25 /lib
parent3548ea8e905269e819fdd4c7fab42142b745c6c5 (diff)
downloadexternal_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.zip
external_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.tar.gz
external_llvm-c70c37794fbff2c615d4f9dc3b6adf9583b855dc.tar.bz2
Fix a case where ScalarEvolution was expanding pointer arithmetic
to inttoptr/ptrtoint unnecessarily. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 3472470..fd37d7b 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -508,20 +508,37 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
}
Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
+ int NumOperands = S->getNumOperands();
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
- Value *V = expand(S->getOperand(S->getNumOperands()-1));
+
+ // Find the index of an operand to start with. Choose the operand with
+ // pointer type, if there is one, or the last operand otherwise.
+ int PIdx = 0;
+ for (; PIdx != NumOperands - 1; ++PIdx)
+ if (isa<PointerType>(S->getOperand(PIdx)->getType())) break;
+
+ // Expand code for the operand that we chose.
+ Value *V = expand(S->getOperand(PIdx));
// Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the
// comments on expandAddToGEP for details.
if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) {
+ // Take the operand at PIdx out of the list.
const SmallVectorImpl<const SCEV *> &Ops = S->getOperands();
- return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1], PTy, Ty, V);
+ SmallVector<const SCEV *, 8> NewOps;
+ NewOps.insert(NewOps.end(), Ops.begin(), Ops.begin() + PIdx);
+ NewOps.insert(NewOps.end(), Ops.begin() + PIdx + 1, Ops.end());
+ // Make a GEP.
+ return expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, V);
}
+ // Otherwise, we'll expand the rest of the SCEVAddExpr as plain integer
+ // arithmetic.
V = InsertNoopCastOfTo(V, Ty);
// Emit a bunch of add instructions
- for (int i = S->getNumOperands()-2; i >= 0; --i) {
+ for (int i = NumOperands-1; i >= 0; --i) {
+ if (i == PIdx) continue;
Value *W = expandCodeFor(S->getOperand(i), Ty);
V = InsertBinop(Instruction::Add, V, W);
}