aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-21 08:39:01 +0000
committerChris Lattner <sabre@nondot.org>2010-11-21 08:39:01 +0000
commitc1da204c433459713cbf4c62f0addf458e6b4b9f (patch)
treeaf8b251973ba78d9350bee23c5e70353a105b431 /lib/Analysis/ConstantFolding.cpp
parentcbd323ad5259dc2bd3428a4ac26718b10adcd3cf (diff)
downloadexternal_llvm-c1da204c433459713cbf4c62f0addf458e6b4b9f.zip
external_llvm-c1da204c433459713cbf4c62f0addf458e6b4b9f.tar.gz
external_llvm-c1da204c433459713cbf4c62f0addf458e6b4b9f.tar.bz2
apply Dan's fix for PR8268 which allows constant folding to handle indexes over
zero sized elements. This allows us to compile: #include <string> void foo() { std::string s; } into an empty function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119933 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index f2e89a7..3ef0356 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -538,7 +538,7 @@ static Constant *CastGEPIndices(Constant *const *Ops, unsigned NumOps,
for (unsigned i = 1; i != NumOps; ++i) {
if ((i == 1 ||
!isa<StructType>(GetElementPtrInst::getIndexedType(Ops[0]->getType(),
- reinterpret_cast<Value *const *>(Ops+1),
+ reinterpret_cast<Value *const *>(Ops+1),
i-1))) &&
Ops[i]->getType() != IntPtrTy) {
Any = true;
@@ -639,12 +639,19 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
// Determine which element of the array the offset points into.
APInt ElemSize(BitWidth, TD->getTypeAllocSize(ATy->getElementType()));
+ const IntegerType *IntPtrTy = TD->getIntPtrType(Ty->getContext());
if (ElemSize == 0)
- return 0;
- APInt NewIdx = Offset.udiv(ElemSize);
- Offset -= NewIdx * ElemSize;
- NewIdxs.push_back(ConstantInt::get(TD->getIntPtrType(Ty->getContext()),
- NewIdx));
+ // The element size is 0. This may be [0 x Ty]*, so just use a zero
+ // index for this level and procede to the next level to see if it can
+ // accomodate the offset.
+ NewIdxs.push_back(ConstantInt::get(IntPtrTy, 0));
+ else {
+ // The element size is non-zero divide the offset by the element
+ // size (rounding down), to compute the index at this level.
+ APInt NewIdx = Offset.udiv(ElemSize);
+ Offset -= NewIdx * ElemSize;
+ NewIdxs.push_back(ConstantInt::get(IntPtrTy, NewIdx));
+ }
Ty = ATy->getElementType();
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
// Determine which field of the struct the offset points into. The
@@ -743,7 +750,8 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD) {
SmallVector<Constant*, 8> Ops;
- for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) {
+ for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end();
+ i != e; ++i) {
Constant *NewC = cast<Constant>(*i);
// Recursively fold the ConstantExpr's operands.
if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC))