summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-01-23 20:41:05 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-01-23 20:41:05 +0000
commitd9c3dabbba5f96b929a3367d7b9701a743d454ea (patch)
tree1675c14a4a1a94ebc17e742ed6783a8daf8910c6 /llvm/lib/Analysis
parent54e311821f679ea12458824b2ac41ffdbae5c195 (diff)
downloadbcm5719-llvm-d9c3dabbba5f96b929a3367d7b9701a743d454ea.tar.gz
bcm5719-llvm-d9c3dabbba5f96b929a3367d7b9701a743d454ea.zip
ConstantFolding: Evaluate GEP indices in the index type.
This fixes some edge cases that we would get wrong with uint64_ts. PR14986. llvm-svn: 173289
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index e2b1e258d7a..95a68bf993e 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -254,13 +254,22 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
if (!CI) return false; // Index isn't a simple constant?
if (CI->isZero()) continue; // Not adding anything.
+ // Evaluate offsets in the index type.
+ APInt APOffset(CI->getBitWidth(), Offset);
+
if (StructType *ST = dyn_cast<StructType>(*GTI)) {
// N = N + Offset
- Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue());
+ APOffset +=
+ APInt(CI->getBitWidth(),
+ TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue()));
} else {
SequentialType *SQT = cast<SequentialType>(*GTI);
- Offset += TD.getTypeAllocSize(SQT->getElementType())*CI->getSExtValue();
+ APOffset +=
+ APInt(CI->getBitWidth(),
+ TD.getTypeAllocSize(SQT->getElementType())*CI->getSExtValue());
}
+
+ Offset = APOffset.getSExtValue();
}
return true;
}
OpenPOWER on IntegriCloud