aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2012-08-23 19:08:53 -0700
committerStephen Hines <srhines@google.com>2012-08-23 19:08:53 -0700
commit31675153bd2d7617db8cb6aeb58054934c7b9f73 (patch)
treec1970fcebc736d4f731db0559a79a7ac5cb0f8bf /lib/Analysis/ConstantFolding.cpp
parent416bb6a168a9316547db6ce3909c515f70a84f52 (diff)
parent75dd7f0c4a2b3fb9e9d4d5a0517591810c57ed92 (diff)
downloadexternal_llvm-31675153bd2d7617db8cb6aeb58054934c7b9f73.zip
external_llvm-31675153bd2d7617db8cb6aeb58054934c7b9f73.tar.gz
external_llvm-31675153bd2d7617db8cb6aeb58054934c7b9f73.tar.bz2
Merge branch 'upstream' into merge_2
Conflicts: lib/Target/ARM/ARMCodeEmitter.cpp Change-Id: I6702d340c733e9721499b5d85b13b96ad9c14eb5
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 7ced848..f5e619c 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -358,17 +358,20 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset,
NumElts = AT->getNumElements();
else
NumElts = cast<VectorType>(C->getType())->getNumElements();
-
+
for (; Index != NumElts; ++Index) {
if (!ReadDataFromGlobal(C->getAggregateElement(Index), Offset, CurPtr,
BytesLeft, TD))
return false;
- if (EltSize >= BytesLeft)
+
+ uint64_t BytesWritten = EltSize - Offset;
+ assert(BytesWritten <= EltSize && "Not indexing into this element?");
+ if (BytesWritten >= BytesLeft)
return true;
-
+
Offset = 0;
- BytesLeft -= EltSize;
- CurPtr += EltSize;
+ BytesLeft -= BytesWritten;
+ CurPtr += BytesWritten;
}
return true;
}
@@ -600,6 +603,22 @@ static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
return C;
}
+/// Strip the pointer casts, but preserve the address space information.
+static Constant* StripPtrCastKeepAS(Constant* Ptr) {
+ assert(Ptr->getType()->isPointerTy() && "Not a pointer type");
+ PointerType *OldPtrTy = cast<PointerType>(Ptr->getType());
+ Ptr = cast<Constant>(Ptr->stripPointerCasts());
+ PointerType *NewPtrTy = cast<PointerType>(Ptr->getType());
+
+ // Preserve the address space number of the pointer.
+ if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) {
+ NewPtrTy = NewPtrTy->getElementType()->getPointerTo(
+ OldPtrTy->getAddressSpace());
+ Ptr = ConstantExpr::getBitCast(Ptr, NewPtrTy);
+ }
+ return Ptr;
+}
+
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
@@ -636,13 +655,13 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
}
return 0;
}
-
+
unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy);
APInt Offset =
APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(),
makeArrayRef((Value **)Ops.data() + 1,
Ops.size() - 1)));
- Ptr = cast<Constant>(Ptr->stripPointerCasts());
+ Ptr = StripPtrCastKeepAS(Ptr);
// If this is a GEP of a GEP, fold it all into a single GEP.
while (GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) {
@@ -661,7 +680,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
Ptr = cast<Constant>(GEP->getOperand(0));
Offset += APInt(BitWidth,
TD->getIndexedOffset(Ptr->getType(), NestedOps));
- Ptr = cast<Constant>(Ptr->stripPointerCasts());
+ Ptr = StripPtrCastKeepAS(Ptr);
}
// If the base value for this address is a literal integer value, fold the