aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-05-22 07:14:20 +0000
committerDan Gohman <gohman@apple.com>2009-05-22 07:14:20 +0000
commite9d60b67368730df22e80dd165ea458c8f4aa549 (patch)
treec9e0b261a7abc0b3c81faa5f6592282888614c89 /lib/Analysis
parent4ae7c211d19d3bd6a6aa6f9bc56458516950a5e7 (diff)
downloadexternal_llvm-e9d60b67368730df22e80dd165ea458c8f4aa549.zip
external_llvm-e9d60b67368730df22e80dd165ea458c8f4aa549.tar.gz
external_llvm-e9d60b67368730df22e80dd165ea458c8f4aa549.tar.bz2
Fix a thinko in the code that adapted SCEVMulExpr operands for
use in expanding SCEVAddExprs with GEPs. The operands of a SCEVMulExpr need to be multiplied together, not added. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72250 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index d110385..507ced7 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -168,6 +168,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEVAddExpr *S,
std::vector<SCEVHandle> ScaledOps;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
if (ElSize != 0) {
+ // For a Constant, check for a multiple of the pointer type's
+ // scale size.
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[i]))
if (!C->getValue()->getValue().srem(ElSize)) {
ConstantInt *CI =
@@ -176,13 +178,19 @@ Value *SCEVExpander::expandAddToGEP(const SCEVAddExpr *S,
ScaledOps.push_back(Div);
continue;
}
+ // In a Mul, check if there is a constant operand which is a multiple
+ // of the pointer type's scale size.
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(Ops[i]))
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
- if (C->getValue()->getValue() == ElSize) {
- for (unsigned j = 1, f = M->getNumOperands(); j != f; ++j)
- ScaledOps.push_back(M->getOperand(j));
+ if (!C->getValue()->getValue().srem(ElSize)) {
+ std::vector<SCEVHandle> NewMulOps(M->getOperands());
+ NewMulOps[0] =
+ SE.getConstant(C->getValue()->getValue().sdiv(ElSize));
+ ScaledOps.push_back(SE.getMulExpr(NewMulOps));
continue;
}
+ // In an Unknown, check if the underlying value is a Mul by a constant
+ // which is equal to the pointer type's scale size.
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Ops[i]))
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U->getValue()))
if (BO->getOpcode() == Instruction::Mul)
@@ -191,6 +199,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEVAddExpr *S,
ScaledOps.push_back(SE.getUnknown(BO->getOperand(0)));
continue;
}
+ // If the pointer type's scale size is 1, no scaling is necessary
+ // and any value can be used.
if (ElSize == 1) {
ScaledOps.push_back(Ops[i]);
continue;