summaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-17 17:59:35 +0000
committerChris Lattner <sabre@nondot.org>2004-11-17 17:59:35 +0000
commit1b9fe1cbbe9bceba688255dc4ef3b3155550b687 (patch)
tree050a7e9977653f46427ab9a2e06ac9e2db27b45a /lib/VMCore
parentbc2a99b4803487202e5521839b7a9e4d5869e5c8 (diff)
downloadexternal_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.cpp29
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);