summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-10-07 14:23:29 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-10-07 14:23:29 +0000
commit17eb3413cdfbe259fa1fd7f532395f1de551d56b (patch)
tree82ad31511ff288dc3164d1de7eb44fa71cbbbc52 /llvm/lib/Analysis
parent88b9d66d4acbff4b88ec91026b1f7df4de326ec2 (diff)
downloadbcm5719-llvm-17eb3413cdfbe259fa1fd7f532395f1de551d56b.tar.gz
bcm5719-llvm-17eb3413cdfbe259fa1fd7f532395f1de551d56b.zip
[ValueTracking] Fix crash in GetPointerBaseWithConstantOffset()
Summary: While walking defs of pointer operands we were assuming that the pointer size would remain constant. This is not true, because addresspacecast instructions may cast the pointer to an address space with a different pointer width. This partial reverts r282612, which was a more conservative solution to this problem. Reviewers: reames, sanjoy, apilipenko Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D24772 llvm-svn: 283557
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp19
1 files changed, 10 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 64a900d2960..6a4aaf1727a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2855,21 +2855,22 @@ Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
break;
if (GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) {
- APInt GEPOffset(BitWidth, 0);
+ // If one of the values we have visited is an addrspacecast, then
+ // the pointer type of this GEP may be different from the type
+ // of the Ptr parameter which was passed to this function. This
+ // means when we construct GEPOffset, we need to use the size
+ // of GEP's pointer type rather than the size of the original
+ // pointer type.
+ APInt GEPOffset(DL.getPointerTypeSizeInBits(Ptr->getType()), 0);
if (!GEP->accumulateConstantOffset(DL, GEPOffset))
break;
- ByteOffset += GEPOffset;
+ ByteOffset += GEPOffset.getSExtValue();
Ptr = GEP->getPointerOperand();
- } else if (Operator::getOpcode(Ptr) == Instruction::BitCast) {
+ } else if (Operator::getOpcode(Ptr) == Instruction::BitCast ||
+ Operator::getOpcode(Ptr) == Instruction::AddrSpaceCast) {
Ptr = cast<Operator>(Ptr)->getOperand(0);
- } else if (AddrSpaceCastInst *ASCI = dyn_cast<AddrSpaceCastInst>(Ptr)) {
- Value *SourcePtr = ASCI->getPointerOperand();
- // Don't look through addrspace cast which changes pointer size
- if (BitWidth != DL.getPointerTypeSizeInBits(SourcePtr->getType()))
- break;
- Ptr = SourcePtr;
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(Ptr)) {
if (GA->isInterposable())
break;
OpenPOWER on IntegriCloud