diff options
author | Chris Lattner <sabre@nondot.org> | 2004-11-17 17:59:35 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-11-17 17:59:35 +0000 |
commit | 1b9fe1cbbe9bceba688255dc4ef3b3155550b687 (patch) | |
tree | 050a7e9977653f46427ab9a2e06ac9e2db27b45a /lib/VMCore | |
parent | bc2a99b4803487202e5521839b7a9e4d5869e5c8 (diff) | |
download | external_llvm-1b9fe1cbbe9bceba688255dc4ef3b3155550b687.zip external_llvm-1b9fe1cbbe9bceba688255dc4ef3b3155550b687.tar.gz external_llvm-1b9fe1cbbe9bceba688255dc4ef3b3155550b687.tar.bz2 |
Generalize this code to turn any cast-to-first-element-of into a gep constexpr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17914 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index d224afe..02b7fe2 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -565,16 +565,29 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, return UndefValue::get(DestTy); } - // Check to see if we are casting an array of X to a pointer to X. If so, use - // a GEP to get to the first element of the array instead of a cast! + // Check to see if we are casting an pointer to an aggregate to a pointer to + // the first element. If so, return the appropriate GEP instruction. if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) - if (const ArrayType *ATy = dyn_cast<ArrayType>(PTy->getElementType())) - if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) - if (DPTy->getElementType() == ATy->getElementType()) { - std::vector<Constant*> IdxList(2,Constant::getNullValue(Type::IntTy)); - return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V), - IdxList); + if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) { + std::vector<Value*> IdxList; + IdxList.push_back(Constant::getNullValue(Type::IntTy)); + const Type *ElTy = PTy->getElementType(); + while (ElTy != DPTy->getElementType()) { + if (const StructType *STy = dyn_cast<StructType>(ElTy)) { + ElTy = STy->getElementType(0); + IdxList.push_back(Constant::getNullValue(Type::UIntTy)); + } else if (const SequentialType *STy = dyn_cast<SequentialType>(ElTy)) { + if (isa<PointerType>(ElTy)) break; // Can't index into pointers! + ElTy = STy->getElementType(); + IdxList.push_back(IdxList[0]); + } else { + break; } + } + + if (ElTy == DPTy->getElementType()) + return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList); + } ConstRules &Rules = ConstRules::get(V, V); |