diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2013-01-23 20:41:05 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2013-01-23 20:41:05 +0000 |
commit | d9c3dabbba5f96b929a3367d7b9701a743d454ea (patch) | |
tree | 1675c14a4a1a94ebc17e742ed6783a8daf8910c6 /llvm/lib/Analysis | |
parent | 54e311821f679ea12458824b2ac41ffdbae5c195 (diff) | |
download | bcm5719-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.cpp | 13 |
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; } |