From c1da204c433459713cbf4c62f0addf458e6b4b9f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 21 Nov 2010 08:39:01 +0000 Subject: [PATCH] apply Dan's fix for PR8268 which allows constant folding to handle indexes over zero sized elements. This allows us to compile: #include 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 --- lib/Analysis/ConstantFolding.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index f2e89a773e7..3ef03569d4e 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(GetElementPtrInst::getIndexedType(Ops[0]->getType(), - reinterpret_cast(Ops+1), + reinterpret_cast(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(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 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(*i); // Recursively fold the ConstantExpr's operands. if (ConstantExpr *NewCE = dyn_cast(NewC))