From f4b42f545b77a81f5db3af7b84131a77a1d2aae3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 8 May 2008 04:54:43 +0000 Subject: Add support for constant folding the 'offsetof' pattern even if the base is not zero. This fixes test/C++Frontend/2008-05-07-CrazyOffsetOf.cpp llvm-svn: 50840 --- llvm/lib/Analysis/ConstantFolding.cpp | 39 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'llvm/lib/Analysis/ConstantFolding.cpp') diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index d58d78f0773..e9efb292e5b 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -122,25 +122,32 @@ static Constant *SymbolicallyEvaluateGEP(Constant* const* Ops, unsigned NumOps, const Type *ResultTy, const TargetData *TD) { Constant *Ptr = Ops[0]; - if (!cast(Ptr->getType())->getElementType()->isSized()) + if (!TD || !cast(Ptr->getType())->getElementType()->isSized()) return 0; - if (TD && Ptr->isNullValue()) { - // If this is a constant expr gep that is effectively computing an - // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' - bool isFoldableGEP = true; - for (unsigned i = 1; i != NumOps; ++i) - if (!isa(Ops[i])) { - isFoldableGEP = false; - break; - } - if (isFoldableGEP) { - uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), - (Value**)Ops+1, NumOps-1); - Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset); - return ConstantExpr::getIntToPtr(C, ResultTy); - } + uint64_t BasePtr = 0; + if (!Ptr->isNullValue()) { + // If this is a inttoptr from a constant int, we can fold this as the base, + // otherwise we can't. + if (ConstantExpr *CE = dyn_cast(Ptr)) + if (CE->getOpcode() == Instruction::IntToPtr) + if (ConstantInt *Base = dyn_cast(CE->getOperand(0))) + BasePtr = Base->getZExtValue(); + + if (BasePtr == 0) + return 0; } + + // If this is a constant expr gep that is effectively computing an + // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' + for (unsigned i = 1; i != NumOps; ++i) + if (!isa(Ops[i])) + return false; + + uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), + (Value**)Ops+1, NumOps-1); + Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset+BasePtr); + return ConstantExpr::getIntToPtr(C, ResultTy); return 0; } -- cgit v1.2.3