aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-02-05 19:04:36 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-02-05 19:04:36 +0000
commita5a9ec5755974fdcd01e76a74f701f494c03817a (patch)
tree5512b875502064b1836925dcebdbaad3051fe239 /llvm/lib/Analysis/ConstantFolding.cpp
parent3be40b56c5409d02339b64992893af367b1fb112 (diff)
downloadllvm-a5a9ec5755974fdcd01e76a74f701f494c03817a.zip
llvm-a5a9ec5755974fdcd01e76a74f701f494c03817a.tar.gz
llvm-a5a9ec5755974fdcd01e76a74f701f494c03817a.tar.bz2
ConstantFolding: Fix a crash when encoutering a truncating inttoptr.
This was introduced in r173293. llvm-svn: 174424
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 400ce72..91424b2 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -545,14 +545,18 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
// constant. This happens frequently when iterating over a global array.
if (Opc == Instruction::Sub && TD) {
GlobalValue *GV1, *GV2;
- APInt Offs1(TD->getPointerSizeInBits(), 0),
- Offs2(TD->getPointerSizeInBits(), 0);
+ unsigned PtrSize = TD->getPointerSizeInBits();
+ unsigned OpSize = TD->getTypeSizeInBits(Op0->getType());
+ APInt Offs1(PtrSize, 0), Offs2(PtrSize, 0);
if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD))
if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) &&
GV1 == GV2) {
// (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
- return ConstantInt::get(Op0->getType(), Offs1-Offs2);
+ // PtrToInt may change the bitwidth so we have convert to the right size
+ // first.
+ return ConstantInt::get(Op0->getType(), Offs1.zextOrTrunc(OpSize) -
+ Offs2.zextOrTrunc(OpSize));
}
}